1 From 5573f16fd05c1f8f310f2ead176b52ed6d4a08ec Mon Sep 17 00:00:00 2001
2 From: Paulo Flabiano Smorigo <pfsmorigo@br.ibm.com>
3 Date: Tue, 30 Oct 2012 15:19:39 -0200
4 Subject: [PATCH] Add vlan-tag support
6 This patch adds support for virtual LAN (VLAN) tagging. VLAN tagging allows
7 multiple VLANs in a bridged network to share the same physical network link but
10 http://en.wikipedia.org/wiki/IEEE_802.1Q
12 This patch should fix this bugzilla:
13 https://bugzilla.redhat.com/show_bug.cgi?id=871563
15 grub-core/kern/ieee1275/init.c | 1 +
16 grub-core/kern/ieee1275/openfw.c | 30 +++++++++++++++++++++++++++
17 grub-core/net/ethernet.c | 42 +++++++++++++++++++++++++++++++++++---
18 include/grub/ieee1275/ieee1275.h | 1 +
19 include/grub/net.h | 2 ++
20 5 files changed, 73 insertions(+), 3 deletions(-)
22 diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
23 index 5c45947..209cf8a 100644
24 --- a/grub-core/kern/ieee1275/init.c
25 +++ b/grub-core/kern/ieee1275/init.c
26 @@ -102,6 +102,7 @@ grub_machine_get_bootlocation (char **device, char **path)
29 dev = grub_ieee1275_get_aliasdevname (bootpath);
30 + grub_ieee1275_parse_net_options (bootpath);
31 canon = grub_ieee1275_canonicalise_devname (dev);
32 ptr = canon + grub_strlen (canon) - 1;
33 while (ptr > canon && (*ptr == ',' || *ptr == ':'))
34 diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c
35 index c2b1bdf..9fdfafa 100644
36 --- a/grub-core/kern/ieee1275/openfw.c
37 +++ b/grub-core/kern/ieee1275/openfw.c
40 #include <grub/ieee1275/ieee1275.h>
42 +#include <grub/env.h>
44 enum grub_ieee1275_parse_type
46 @@ -413,6 +414,35 @@ fail:
51 +grub_ieee1275_parse_net_options (const char *path)
57 + args = grub_ieee1275_get_devargs (path);
59 + /* There is no option. */
64 + comma = grub_strchr (args, ',');
66 + option = grub_strdup (args);
68 + option = grub_strndup (args, (grub_size_t)(comma - args));
71 + if (! grub_strncmp(option, "vtag", 4))
72 + grub_env_set ("vlan-tag", option + grub_strlen("vtag="));
80 grub_ieee1275_get_device_type (const char *path)
82 diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c
83 index b38e2c8..5e45d46 100644
84 --- a/grub-core/net/ethernet.c
85 +++ b/grub-core/net/ethernet.c
87 #include <grub/net/arp.h>
88 #include <grub/net/netbuff.h>
90 +#include <grub/env.h>
91 #include <grub/time.h>
92 #include <grub/net/arp.h>
94 @@ -56,10 +57,19 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf,
98 + grub_uint32_t vlantag = 0;
99 + grub_uint8_t etherhdr_size;
101 - COMPILE_TIME_ASSERT (sizeof (*eth) < GRUB_NET_MAX_LINK_HEADER_SIZE);
102 + etherhdr_size = sizeof (*eth);
103 + COMPILE_TIME_ASSERT (sizeof (*eth) + 4 < GRUB_NET_MAX_LINK_HEADER_SIZE);
105 - err = grub_netbuff_push (nb, sizeof (*eth));
106 + const char *vlantag_text = grub_env_get ("vlan-tag");
107 + if (vlantag_text != 0) {
108 + etherhdr_size += 4;
109 + vlantag = grub_strtoul (vlantag_text, 0, 16);
112 + err = grub_netbuff_push (nb, etherhdr_size);
115 eth = (struct etherhdr *) nb->data;
116 @@ -76,6 +86,19 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf,
118 inf->card->opened = 1;
121 + /* Check if a vlan-tag is needed. */
124 + /* Move eth type to the right */
125 + grub_memcpy((char *) nb->data + etherhdr_size - 2,
126 + (char *) nb->data + etherhdr_size - 6, 2);
128 + /* Add the tag in the middle */
129 + grub_memcpy((char *) nb->data + etherhdr_size - 6,
133 return inf->card->driver->send (inf->card, nb);
136 @@ -90,10 +113,23 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb,
137 grub_net_link_level_address_t hwaddress;
138 grub_net_link_level_address_t src_hwaddress;
140 + grub_uint8_t etherhdr_size = sizeof (*eth);
142 + grub_uint16_t vlantag_identifier = 0;
143 + grub_memcpy (&vlantag_identifier, nb->data + etherhdr_size - 2, 2);
145 + /* Check if a vlan-tag is present. */
146 + if (vlantag_identifier == VLANTAG_IDENTIFIER)
148 + etherhdr_size += 4;
149 + /* Move eth type to the original position */
150 + grub_memcpy((char *) nb->data + etherhdr_size - 6,
151 + (char *) nb->data + etherhdr_size - 2, 2);
154 eth = (struct etherhdr *) nb->data;
155 type = grub_be_to_cpu16 (eth->type);
156 - err = grub_netbuff_pull (nb, sizeof (*eth));
157 + err = grub_netbuff_pull (nb, etherhdr_size);
161 diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h
162 index 416a544..a8cf093 100644
163 --- a/include/grub/ieee1275/ieee1275.h
164 +++ b/include/grub/ieee1275/ieee1275.h
165 @@ -210,5 +210,6 @@ char *EXPORT_FUNC(grub_ieee1275_canonicalise_devname) (const char *path);
166 char *EXPORT_FUNC(grub_ieee1275_get_aliasdevname) (const char *path);
167 char *EXPORT_FUNC(grub_ieee1275_canonicalise_devname) (const char *path);
168 char *EXPORT_FUNC(grub_ieee1275_get_device_type) (const char *path);
169 +int EXPORT_FUNC(grub_ieee1275_parse_net_options) (const char *path);
171 #endif /* ! GRUB_IEEE1275_HEADER */
172 diff --git a/include/grub/net.h b/include/grub/net.h
173 index a7e5b2c..f4fec17 100644
174 --- a/include/grub/net.h
175 +++ b/include/grub/net.h
176 @@ -532,4 +532,6 @@ extern char *grub_net_default_server;
177 #define GRUB_NET_TRIES 40
178 #define GRUB_NET_INTERVAL 400
180 +#define VLANTAG_IDENTIFIER 0x8100
182 #endif /* ! GRUB_NET_HEADER */