]> TLD Linux GIT Repositories - packages/grub2.git/blob - add-vlan-tag-support.patch
- grub2 from PLD
[packages/grub2.git] / add-vlan-tag-support.patch
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
5
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
8 maintain isolation:
9
10 http://en.wikipedia.org/wiki/IEEE_802.1Q
11
12 This patch should fix this bugzilla:
13 https://bugzilla.redhat.com/show_bug.cgi?id=871563
14 ---
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(-)
21
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)
27        char *dev, *canon;
28        char *ptr;
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
38 @@ -23,6 +23,7 @@
39  #include <grub/mm.h>
40  #include <grub/ieee1275/ieee1275.h>
41  #include <grub/net.h>
42 +#include <grub/env.h>
43  
44  enum grub_ieee1275_parse_type
45  {
46 @@ -413,6 +414,35 @@ fail:
47    return ret;
48  }
49  
50 +int
51 +grub_ieee1275_parse_net_options (const char *path)
52 +{
53 +  char *comma;
54 +  char *args;
55 +  char *option = 0;
56 +
57 +  args = grub_ieee1275_get_devargs (path);
58 +  if (!args)
59 +    /* There is no option.  */
60 +    return -1;
61 +
62 +  do
63 +    {
64 +      comma = grub_strchr (args, ',');
65 +      if (! comma)
66 +        option = grub_strdup (args);
67 +      else
68 +        option = grub_strndup (args, (grub_size_t)(comma - args));
69 +      args = comma + 1;
70 +
71 +      if (! grub_strncmp(option, "vtag", 4))
72 +          grub_env_set ("vlan-tag", option + grub_strlen("vtag="));
73 +
74 +    } while (comma);
75 +
76 +  return 0;
77 +}
78 +
79  char *
80  grub_ieee1275_get_device_type (const char *path)
81  {
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
86 @@ -23,6 +23,7 @@
87  #include <grub/net/arp.h>
88  #include <grub/net/netbuff.h>
89  #include <grub/net.h>
90 +#include <grub/env.h>
91  #include <grub/time.h>
92  #include <grub/net/arp.h>
93  
94 @@ -56,10 +57,19 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf,
95  {
96    struct etherhdr *eth;
97    grub_err_t err;
98 +  grub_uint32_t vlantag = 0;
99 +  grub_uint8_t etherhdr_size;
100  
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);
104  
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);
110 +  }
111 +
112 +  err = grub_netbuff_push (nb, etherhdr_size);
113    if (err)
114      return err;
115    eth = (struct etherhdr *) nb->data;
116 @@ -76,6 +86,19 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf,
117         return err;
118        inf->card->opened = 1;
119      }
120 +
121 +  /* Check if a vlan-tag is needed. */
122 +  if (vlantag != 0)
123 +    {
124 +      /* Move eth type to the right */
125 +      grub_memcpy((char *) nb->data + etherhdr_size - 2,
126 +                  (char *) nb->data + etherhdr_size - 6, 2);
127 +
128 +      /* Add the tag in the middle */
129 +      grub_memcpy((char *) nb->data + etherhdr_size - 6,
130 +                  &vlantag, 4);
131 +    }
132 +
133    return inf->card->driver->send (inf->card, nb);
134  }
135  
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;
139    grub_err_t err;
140 +  grub_uint8_t etherhdr_size = sizeof (*eth);
141 +
142 +  grub_uint16_t vlantag_identifier = 0;
143 +  grub_memcpy (&vlantag_identifier, nb->data + etherhdr_size - 2, 2);
144 +
145 +  /* Check if a vlan-tag is present. */
146 +  if (vlantag_identifier == VLANTAG_IDENTIFIER)
147 +    {
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);
152 +    }
153  
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);
158    if (err)
159      return err;
160  
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);
170  
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
179  
180 +#define VLANTAG_IDENTIFIER 0x8100
181 +
182  #endif /* ! GRUB_NET_HEADER */
183 -- 
184 1.7.10.4
185