grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Request a freeze exception for vlantag feature


From: Paulo Flabiano Smorigo
Subject: Re: Request a freeze exception for vlantag feature
Date: Wed, 8 Jan 2014 16:57:28 -0200
User-agent: Mutt/null+5621 (d3096e8796e7) (2012-12-30)

Thu, Dec 26, 2013 at 03:25:28PM -0200, address@hidden wrote:
> Mon, Dec 23, 2013 at 09:02:57PM +0400, Andrey Borzenkov wrote:
> > В Пн, 23/12/2013 в 11:34 -0500, Paulo Flabiano Smorigo/Brazil/IBM пишет:
> > > Hello everyone,
> > > 
> > > With the consent of Vladimir Serbinenko, I committed three patches in  
> > > the next branch. Those patches add support for virtual LAN (VLAN)  
> > > tagging. VLAN tagging allows multiple VLANs in a bridged network to  
> > > share the same physical network link but maintain isolation:
> > > 
> > > http://en.wikipedia.org/wiki/IEEE_802.1Q
> > > 
> > > http://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=11454e94ea8e78317b9c9ab22855e26890880745
> > > http://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=8ff3c31f6d59ca758b3bc0020e5140dcc937edd6
> > > http://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=af768f8d4166aae41bbac8575fca7c65a319bfdb
> > > 
> > > 
> > 
> > VLAN tag is 12 bits, with 4 remaining bits being packet priority. You
> > need to mask them off before comparing. 
> > 
> 
> Tks for the feedback. I fixed it. Can you take a look?
> 
> http://git.io/ol5y-Q
> 
> > A couple of words in documentation would be nice (are those variables
> > for this platform documented at all?)
> 
> Ok, I'll will add a documentation.
> 
> 
> Btw, I need to add it to the commands. I'm not sure if I add a parameter
> to net_add_addr and net_bootp or create a new one to set it.
> 
> > 
> > > I come here to ask for an freeze exception so it can be also in master  
> > > and in 2.02 release.
> > >
> > > Thanks in advance,
> > > --
> > > Paulo Flabiano Smorigo
> > > Software Engineer
> > > Linux Technology Center - IBM Systems & Technology Group
> > > 
> > > 
> > > _______________________________________________
> > > Grub-devel mailing list
> > > address@hidden
> > > https://lists.gnu.org/mailman/listinfo/grub-devel
> > 
> > 
> > 
> > 
> > _______________________________________________
> > Grub-devel mailing list
> > address@hidden
> > https://lists.gnu.org/mailman/listinfo/grub-devel
> 
> -- 
> --
> Paulo Flabiano Smorigo
> IBM Linux Technology Center
> 
> 
> _______________________________________________
> Grub-devel mailing list
> address@hidden
> https://lists.gnu.org/mailman/listinfo/grub-devel

This is a reviewed version of the patch. I added vlantag option to the 
net_add_addr
and net_bootp commands.

---
 grub-core/net/arp.c                    |  8 +++---
 grub-core/net/bootp.c                  | 24 ++++++++++++++---
 grub-core/net/drivers/ieee1275/ofnet.c |  6 ++++-
 grub-core/net/ethernet.c               | 20 +++++++-------
 grub-core/net/ip.c                     | 22 +++++++--------
 grub-core/net/net.c                    | 49 +++++++++++++++++++++++++++++++---
 include/grub/net.h                     | 11 +++++++-
 include/grub/net/arp.h                 |  2 +-
 include/grub/net/ip.h                  |  2 +-
 9 files changed, 110 insertions(+), 34 deletions(-)

diff --git a/grub-core/net/arp.c b/grub-core/net/arp.c
index 2e3cf44..8485ff2 100644
--- a/grub-core/net/arp.c
+++ b/grub-core/net/arp.c
@@ -122,7 +122,7 @@ grub_net_arp_send_request (struct 
grub_net_network_level_interface *inf,
 
 grub_err_t
 grub_net_arp_receive (struct grub_net_buff *nb, struct grub_net_card *card,
-                      grub_uint16_t *vlantag)
+                      grub_uint16_t vlantag_vid)
 {
   struct arphdr *arp_header = (struct arphdr *) nb->data;
   grub_uint8_t *sender_hardware_address;
@@ -158,11 +158,11 @@ grub_net_arp_receive (struct grub_net_buff *nb, struct 
grub_net_card *card,
   FOR_NET_NETWORK_LEVEL_INTERFACES (inf)
   {
     /* Verify vlantag id */
-    if (inf->card == card && inf->vlantag != *vlantag)
+    if (inf->card == card && inf->vlantag.vid != vlantag_vid)
       {
         grub_dprintf ("net", "invalid vlantag! %x != %x\n",
-                      inf->vlantag, *vlantag);
-        break;
+                      inf->vlantag.vid, vlantag_vid);
+        continue;
       }
 
     /* Am I the protocol address target? */
diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c
index 6310ed4..4c4217a 100644
--- a/grub-core/net/bootp.c
+++ b/grub-core/net/bootp.c
@@ -425,10 +425,12 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ 
((unused)),
   unsigned j = 0;
   int interval;
   grub_err_t err;
+  grub_int8_t vlan_pos = -1;
 
   FOR_NET_CARDS (card)
   {
-    if (argc > 0 && grub_strcmp (card->name, args[0]) != 0)
+    if (argc > 0 && grub_strcmp (card->name, args[0]) != 0 &&
+        grub_strcmp (args[0], "vlan") != 0)
       continue;
     ncards++;
   }
@@ -443,7 +445,8 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ 
((unused)),
   j = 0;
   FOR_NET_CARDS (card)
   {
-    if (argc > 0 && grub_strcmp (card->name, args[0]) != 0)
+    if (argc > 0 && grub_strcmp (card->name, args[0]) != 0 &&
+        grub_strcmp (args[0], "vlan") != 0)
       continue;
     ifaces[j].card = card;
     ifaces[j].next = &ifaces[j+1];
@@ -462,6 +465,21 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ 
((unused)),
     ifaces[j].address.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV;
     grub_memcpy (&ifaces[j].hwaddress, &card->default_address, 
                 sizeof (ifaces[j].hwaddress));
+
+    if (grub_strcmp (args[0], "vlan") == 0)
+      vlan_pos = 0;
+
+    if (grub_strcmp (args[1], "vlan") == 0)
+      vlan_pos = 1;
+
+    if (vlan_pos != -1)
+      {
+        if (argc == vlan_pos + 4)
+          grub_set_vlantag (&ifaces[j].vlantag, &args[vlan_pos]);
+        else
+          return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                             N_("five arguments expected"));
+      }
     j++;
   }
   ifaces[ncards - 1].next = grub_net_network_level_interfaces;
@@ -570,7 +588,7 @@ void
 grub_bootp_init (void)
 {
   cmd_bootp = grub_register_command ("net_bootp", grub_cmd_bootp,
-                                    N_("[CARD]"),
+                                    N_("[CARD] [vlan PCP DEI VID]"),
                                     N_("perform a bootp autoconfiguration"));
   cmd_getdhcp = grub_register_command ("net_get_dhcp_option", grub_cmd_dhcpopt,
                                       N_("VAR INTERFACE NUMBER DESCRIPTION"),
diff --git a/grub-core/net/drivers/ieee1275/ofnet.c 
b/grub-core/net/drivers/ieee1275/ofnet.c
index 956d12d..ffcb943 100644
--- a/grub-core/net/drivers/ieee1275/ofnet.c
+++ b/grub-core/net/drivers/ieee1275/ofnet.c
@@ -212,7 +212,11 @@ grub_ieee1275_parse_bootargs (const char *devpath, char 
*bootpath,
                                   hw_addr.mac, sizeof(hw_addr.mac), 0);
       inter = grub_net_add_addr ((*card)->name, *card, &client_addr, &hw_addr,
                                  flags);
-      inter->vlantag = vlantag;
+
+      inter->vlantag.pcp = vlantag >> 12;
+      inter->vlantag.dei = (vlantag >> 11) & 0x1;
+      inter->vlantag.vid = vlantag & 0x1fff;
+
       grub_net_add_ipv4_local (inter,
                           __builtin_ctz (~grub_le_to_cpu32 
(subnet_mask.ipv4)));
 
diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c
index 4d7ceed..ae195bc 100644
--- a/grub-core/net/ethernet.c
+++ b/grub-core/net/ethernet.c
@@ -58,13 +58,12 @@ send_ethernet_packet (struct 
grub_net_network_level_interface *inf,
   struct etherhdr *eth;
   grub_err_t err;
   grub_uint8_t etherhdr_size;
-  grub_uint16_t vlantag_id = VLANTAG_IDENTIFIER;
 
   etherhdr_size = sizeof (*eth);
   COMPILE_TIME_ASSERT (sizeof (*eth) + 4 < GRUB_NET_MAX_LINK_HEADER_SIZE);
 
   /* Increase ethernet header in case of vlantag */
-  if (inf->vlantag != 0)
+  if (inf->vlantag.vid != 0)
     etherhdr_size += 4;
 
   err = grub_netbuff_push (nb, etherhdr_size);
@@ -86,15 +85,18 @@ send_ethernet_packet (struct 
grub_net_network_level_interface *inf,
     }
 
   /* Check and add a vlan-tag if needed. */
-  if (inf->vlantag != 0)
+  if (inf->vlantag.vid != 0)
     {
+      grub_uint32_t vlantag;
+      vlantag = (VLANTAG_IDENTIFIER << 16) + (inf->vlantag.pcp << 12) +
+                (inf->vlantag.dei << 11) + inf->vlantag.vid;
+
       /* Move eth type to the right */
       grub_memcpy ((char *) nb->data + etherhdr_size - 2,
                    (char *) nb->data + etherhdr_size - 6, 2);
 
       /* Add the tag in the middle */
-      grub_memcpy ((char *) nb->data + etherhdr_size - 6, &vlantag_id, 2);
-      grub_memcpy ((char *) nb->data + etherhdr_size - 4, (char *) 
&(inf->vlantag), 2);
+      grub_memcpy ((char *) nb->data + etherhdr_size - 6, &vlantag, 4);
     }
 
   return inf->card->driver->send (inf->card, nb);
@@ -112,7 +114,7 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb,
   grub_net_link_level_address_t src_hwaddress;
   grub_err_t err;
   grub_uint8_t etherhdr_size = sizeof (*eth);
-  grub_uint16_t vlantag = 0;
+  grub_uint16_t vlantag_vid = 0;
 
 
   /* Check if a vlan-tag is present. If so, the ethernet header is 4 bytes */
@@ -120,7 +122,7 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb,
   /* is reseted to the original size. */
   if (grub_get_unaligned16 (nb->data + etherhdr_size - 2) == 
VLANTAG_IDENTIFIER)
     {
-      vlantag = grub_get_unaligned16 (nb->data + etherhdr_size);
+      vlantag_vid = grub_get_unaligned16 (nb->data + etherhdr_size) & 0x1fff;
       etherhdr_size += 4;
       /* Move eth type to the original position */
       grub_memcpy((char *) nb->data + etherhdr_size - 6,
@@ -157,14 +159,14 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb,
     {
       /* ARP packet. */
     case GRUB_NET_ETHERTYPE_ARP:
-      grub_net_arp_receive (nb, card, &vlantag);
+      grub_net_arp_receive (nb, card, vlantag_vid);
       grub_netbuff_free (nb);
       return GRUB_ERR_NONE;
       /* IP packet.  */
     case GRUB_NET_ETHERTYPE_IP:
     case GRUB_NET_ETHERTYPE_IP6:
       return grub_net_recv_ip_packets (nb, card, &hwaddress, &src_hwaddress,
-                                       &vlantag);
+                                       vlantag_vid);
     }
   grub_netbuff_free (nb);
   return GRUB_ERR_NONE;
diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c
index b21bc6f..9919caa 100644
--- a/grub-core/net/ip.c
+++ b/grub-core/net/ip.c
@@ -225,7 +225,7 @@ handle_dgram (struct grub_net_buff *nb,
              grub_net_ip_protocol_t proto,
              const grub_net_network_level_address_t *source,
              const grub_net_network_level_address_t *dest,
-              grub_uint16_t *vlantag,
+              grub_uint16_t vlantag_vid,
              grub_uint8_t ttl)
 {
   struct grub_net_network_level_interface *inf = NULL;
@@ -293,10 +293,10 @@ handle_dgram (struct grub_net_buff *nb,
       break;
 
     /* Verify vlantag id */
-    if (inf->card == card && inf->vlantag != *vlantag)
+    if (inf->card == card && inf->vlantag.vid != vlantag_vid)
       {
         grub_dprintf ("net", "invalid vlantag! %x != %x\n",
-                      inf->vlantag, *vlantag);
+                      inf->vlantag.vid, vlantag_vid);
         break;
       }
 
@@ -389,7 +389,7 @@ grub_net_recv_ip4_packets (struct grub_net_buff *nb,
                           struct grub_net_card *card,
                           const grub_net_link_level_address_t *hwaddress,
                           const grub_net_link_level_address_t *src_hwaddress,
-                           grub_uint16_t *vlantag)
+                           grub_uint16_t vlantag_vid)
 {
   struct iphdr *iph = (struct iphdr *) nb->data;
   grub_err_t err;
@@ -464,7 +464,7 @@ grub_net_recv_ip4_packets (struct grub_net_buff *nb,
       dest.ipv4 = iph->dest;
 
       return handle_dgram (nb, card, src_hwaddress, hwaddress, iph->protocol,
-                          &source, &dest, vlantag, iph->ttl);
+                          &source, &dest, vlantag_vid, iph->ttl);
     }
 
   for (prev = &reassembles, rsm = *prev; rsm; prev = &rsm->next, rsm = *prev)
@@ -600,7 +600,7 @@ grub_net_recv_ip4_packets (struct grub_net_buff *nb,
       dest.ipv4 = dst;
 
       return handle_dgram (ret, card, src_hwaddress,
-                          hwaddress, proto, &source, &dest, vlantag,
+                          hwaddress, proto, &source, &dest, vlantag_vid,
                           ttl);
     }
 }
@@ -656,7 +656,7 @@ grub_net_recv_ip6_packets (struct grub_net_buff *nb,
                           struct grub_net_card *card,
                           const grub_net_link_level_address_t *hwaddress,
                           const grub_net_link_level_address_t *src_hwaddress,
-                           grub_uint16_t *vlantag)
+                           grub_uint16_t vlantag_vid)
 {
   struct ip6hdr *iph = (struct ip6hdr *) nb->data;
   grub_err_t err;
@@ -707,7 +707,7 @@ grub_net_recv_ip6_packets (struct grub_net_buff *nb,
   grub_memcpy (dest.ipv6, &iph->dest, sizeof (dest.ipv6));
 
   return handle_dgram (nb, card, src_hwaddress, hwaddress, iph->protocol,
-                      &source, &dest, vlantag, iph->ttl);
+                      &source, &dest, vlantag_vid, iph->ttl);
 }
 
 grub_err_t
@@ -715,16 +715,16 @@ grub_net_recv_ip_packets (struct grub_net_buff *nb,
                          struct grub_net_card *card,
                          const grub_net_link_level_address_t *hwaddress,
                          const grub_net_link_level_address_t *src_hwaddress,
-                          grub_uint16_t *vlantag)
+                          grub_uint16_t vlantag_vid)
 {
   struct iphdr *iph = (struct iphdr *) nb->data;
 
   if ((iph->verhdrlen >> 4) == 4)
     return grub_net_recv_ip4_packets (nb, card, hwaddress, src_hwaddress,
-                                      vlantag);
+                                      vlantag_vid);
   if ((iph->verhdrlen >> 4) == 6)
     return grub_net_recv_ip6_packets (nb, card, hwaddress, src_hwaddress,
-                                      vlantag);
+                                      vlantag_vid);
   grub_dprintf ("net", "Bad IP version: %d\n", (iph->verhdrlen >> 4));
   grub_netbuff_free (nb);
   return GRUB_ERR_NONE;
diff --git a/grub-core/net/net.c b/grub-core/net/net.c
index 8f9d183..6afe80f 100644
--- a/grub-core/net/net.c
+++ b/grub-core/net/net.c
@@ -1014,6 +1014,26 @@ grub_net_add_ipv4_local (struct 
grub_net_network_level_interface *inter,
   return 0;
 }
 
+grub_err_t
+grub_set_vlantag (struct grub_net_vlantag *vlantag, char **args)
+{
+      grub_uint16_t value;
+
+      value = grub_strtoul (args[1], 0, 0);
+      if (value <= 7)
+        vlantag->pcp = value;
+
+      value = grub_strtoul (args[2], 0, 0);
+      if (value <= 1)
+        vlantag->dei = value;
+
+      value = grub_strtoul (args[3], 0, 0);
+      if (value <= 4095)
+        vlantag->vid = value;
+
+      return GRUB_ERR_NONE;
+}
+
 /* FIXME: support MAC specifying.  */
 static grub_err_t
 grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)),
@@ -1024,8 +1044,9 @@ grub_cmd_addaddr (struct grub_command *cmd __attribute__ 
((unused)),
   grub_err_t err;
   grub_net_interface_flags_t flags = 0;
   struct grub_net_network_level_interface *inf;
+  grub_int8_t vlan_pos = -1;
 
-  if (argc != 3)
+  if (argc < 3)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("three arguments expected"));
   
   FOR_NET_CARDS (card)
@@ -1047,6 +1068,22 @@ grub_cmd_addaddr (struct grub_command *cmd __attribute__ 
((unused)),
 
   inf = grub_net_add_addr (args[0], card, &addr, &card->default_address,
                           flags);
+
+  if (grub_strcmp (args[3], "vlan") == 0)
+    vlan_pos = 3;
+
+  if (grub_strcmp (args[4], "vlan") == 0)
+    vlan_pos = 4;
+
+  if (vlan_pos != -1)
+    {
+      if (argc == vlan_pos + 4)
+        grub_set_vlantag (&inf->vlantag, &args[vlan_pos]);
+      else
+        return grub_error (GRUB_ERR_BAD_ARGUMENT,
+                           N_("seven arguments expected"));
+    }
+
   if (inf)
     grub_net_add_ipv4_local (inf, -1);
 
@@ -1257,7 +1294,13 @@ grub_cmd_listaddrs (struct grub_command *cmd 
__attribute__ ((unused)),
     char bufn[GRUB_NET_MAX_STR_ADDR_LEN];
     grub_net_hwaddr_to_str (&inf->hwaddress, bufh);
     grub_net_addr_to_str (&inf->address, bufn);
-    grub_printf ("%s %s %s\n", inf->name, bufh, bufn);
+    grub_printf ("%s %s %s", inf->name, bufh, bufn);
+
+    if (inf->vlantag.vid > 0)
+        grub_printf (" vlan %u %u %u\n", inf->vlantag.pcp, inf->vlantag.dei,
+                     inf->vlantag.vid);
+    else
+        grub_printf ("\n");
   }
   return GRUB_ERR_NONE;
 }
@@ -1725,7 +1768,7 @@ GRUB_MOD_INIT(net)
   cmd_addaddr = grub_register_command ("net_add_addr", grub_cmd_addaddr,
                                        /* TRANSLATORS: HWADDRESS stands for
                                           "hardware address".  */
-                                      N_("SHORTNAME CARD ADDRESS [HWADDRESS]"),
+                                      N_("SHORTNAME CARD ADDRESS [HWADDRESS] 
[vlan PCP DEI VID]"),
                                       N_("Add a network address."));
   cmd_slaac = grub_register_command ("net_ipv6_autoconf",
                                     grub_cmd_ipv6_autoconf,
diff --git a/include/grub/net.h b/include/grub/net.h
index cce3eda..7c0847b 100644
--- a/include/grub/net.h
+++ b/include/grub/net.h
@@ -268,6 +268,13 @@ typedef struct grub_net
 
 extern grub_net_t (*EXPORT_VAR (grub_net_open)) (const char *name);
 
+struct grub_net_vlantag
+{
+    grub_uint8_t pcp;
+    grub_uint8_t dei;
+    grub_uint16_t vid;
+};
+
 struct grub_net_network_level_interface
 {
   struct grub_net_network_level_interface *next;
@@ -279,7 +286,7 @@ struct grub_net_network_level_interface
   grub_net_interface_flags_t flags;
   struct grub_net_bootp_packet *dhcp_ack;
   grub_size_t dhcp_acklen;
-  grub_uint16_t vlantag;
+  struct grub_net_vlantag vlantag;
   void *data;
 };
 
@@ -395,6 +402,8 @@ grub_net_add_route_gw (const char *name,
                       grub_net_network_level_netaddress_t target,
                       grub_net_network_level_address_t gw);
 
+grub_err_t
+grub_set_vlantag (struct grub_net_vlantag *vlantag, char **args);
 
 #define GRUB_NET_BOOTP_MAC_ADDR_LEN    16
 
diff --git a/include/grub/net/arp.h b/include/grub/net/arp.h
index 8d9d081..56336b3 100644
--- a/include/grub/net/arp.h
+++ b/include/grub/net/arp.h
@@ -23,7 +23,7 @@
 
 extern grub_err_t grub_net_arp_receive (struct grub_net_buff *nb,
                                         struct grub_net_card *card,
-                                        grub_uint16_t *vlantag);
+                                        grub_uint16_t vlantag_vid);
 
 grub_err_t
 grub_net_arp_send_request (struct grub_net_network_level_interface *inf,
diff --git a/include/grub/net/ip.h b/include/grub/net/ip.h
index 39062df..e79dec9 100644
--- a/include/grub/net/ip.h
+++ b/include/grub/net/ip.h
@@ -49,7 +49,7 @@ grub_net_recv_ip_packets (struct grub_net_buff *nb,
                          struct grub_net_card *card,
                          const grub_net_link_level_address_t *hwaddress,
                          const grub_net_link_level_address_t *src_hwaddress,
-                          grub_uint16_t *vlantag);
+                          grub_uint16_t vlantag_vid);
 
 grub_err_t
 grub_net_send_ip_packet (struct grub_net_network_level_interface *inf,








reply via email to

[Prev in Thread] Current Thread [Next in Thread]