[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] [next] net: VLAN cleanup
From: |
Andrei Borzenkov |
Subject: |
[PATCH] [next] net: VLAN cleanup |
Date: |
Mon, 7 Mar 2016 23:40:19 +0300 |
- strip priority bits in received packets. We do not control them and need
to compare VLAN number only, which takes just 12 bits.
- store VLAN number and priority bits separately in interface structure.
- fix VLAN comparison when searching for matching interface. We need to
continiue, not break out of loop, if VLAN number does not match.
- add missing VLAN check in BOOTP/DHCP processing.
- introduce 802.1Q header structure to avoid shuffling parts of packet around.
This streamlines code and makes it more clear.
- remove misleading dprintf - non-matching VLAN is not really an error. It is
quite possible to have multiple interfaces on the same physical card with
different VLAN numbers.
- pass VLAN number by value, there is no need to use reference.
- print VLAN ID in net_ls_addr
---
grub-core/net/arp.c | 10 ++---
grub-core/net/drivers/ieee1275/ofnet.c | 4 +-
grub-core/net/ethernet.c | 79 +++++++++++++++++-----------------
grub-core/net/ip.c | 21 ++++-----
grub-core/net/net.c | 5 ++-
include/grub/net.h | 3 +-
include/grub/net/arp.h | 2 +-
include/grub/net/ethernet.h | 1 +
include/grub/net/ip.h | 2 +-
9 files changed, 62 insertions(+), 65 deletions(-)
diff --git a/grub-core/net/arp.c b/grub-core/net/arp.c
index 54306e3..2c57032 100644
--- a/grub-core/net/arp.c
+++ b/grub-core/net/arp.c
@@ -112,7 +112,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)
{
struct arppkt *arp_packet = (struct arppkt *) nb->data;
grub_net_network_level_address_t sender_addr, target_addr;
@@ -139,12 +139,8 @@ 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)
- {
- grub_dprintf ("net", "invalid vlantag! %x != %x\n",
- inf->vlantag, *vlantag);
- break;
- }
+ if (inf->vlantag != vlantag)
+ continue;
/* Am I the protocol address target? */
if (grub_net_addr_cmp (&inf->address, &target_addr) == 0
diff --git a/grub-core/net/drivers/ieee1275/ofnet.c
b/grub-core/net/drivers/ieee1275/ofnet.c
index 9d83c9f..0283a51 100644
--- a/grub-core/net/drivers/ieee1275/ofnet.c
+++ b/grub-core/net/drivers/ieee1275/ofnet.c
@@ -212,10 +212,10 @@ 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 = vlantag & 0xfff;
+ inter->prio = vlantag & 0xf000;
grub_net_add_ipv4_local (inter,
__builtin_ctz (~grub_le_to_cpu32
(subnet_mask.ipv4)));
-
}
if (gateway_addr.ipv4 != 0)
diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c
index 4d7ceed..3541d8c 100644
--- a/grub-core/net/ethernet.c
+++ b/grub-core/net/ethernet.c
@@ -36,6 +36,12 @@ struct etherhdr
grub_uint16_t type;
} GRUB_PACKED;
+struct vlanhdr
+{
+ grub_uint16_t vtag;
+ grub_uint16_t type;
+} GRUB_PACKED;
+
struct llchdr
{
grub_uint8_t dsap;
@@ -56,18 +62,25 @@ send_ethernet_packet (struct
grub_net_network_level_interface *inf,
grub_net_ethertype_t ethertype)
{
struct etherhdr *eth;
+ struct vlanhdr *vlan;
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);
+ COMPILE_TIME_ASSERT (sizeof (*eth) + sizeof (*vlan) <
GRUB_NET_MAX_LINK_HEADER_SIZE);
- /* Increase ethernet header in case of vlantag */
- if (inf->vlantag != 0)
- etherhdr_size += 4;
+ /* Add 802.1Q header in case of vlantag or priority */
+ if (inf->vlantag || inf->prio)
+ {
+ err = grub_netbuff_push (nb, sizeof (*vlan));
+ if (err)
+ return err;
- err = grub_netbuff_push (nb, etherhdr_size);
+ vlan = (struct vlanhdr *) nb->data;
+ vlan->vtag = grub_cpu_to_be16 (inf->vlantag | inf->prio);
+ vlan->type = grub_cpu_to_be16 (ethertype);
+ ethertype = GRUB_NET_ETHERTYPE_802_1Q;
+ }
+
+ err = grub_netbuff_push (nb, sizeof (*eth));
if (err)
return err;
eth = (struct etherhdr *) nb->data;
@@ -84,19 +97,6 @@ send_ethernet_packet (struct
grub_net_network_level_interface *inf,
return err;
inf->card->opened = 1;
}
-
- /* Check and add a vlan-tag if needed. */
- if (inf->vlantag != 0)
- {
- /* 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);
- }
-
return inf->card->driver->send (inf->card, nb);
}
@@ -105,33 +105,31 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb,
struct grub_net_card *card)
{
struct etherhdr *eth;
+ struct vlanhdr *vlan;
struct llchdr *llch;
struct snaphdr *snaph;
grub_net_ethertype_t type;
grub_net_link_level_address_t hwaddress;
grub_net_link_level_address_t src_hwaddress;
grub_err_t err;
- grub_uint8_t etherhdr_size = sizeof (*eth);
grub_uint16_t vlantag = 0;
-
- /* Check if a vlan-tag is present. If so, the ethernet header is 4 bytes */
- /* longer than the original one. The vlantag id is extracted and the header
*/
- /* 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);
- etherhdr_size += 4;
- /* Move eth type to the original position */
- grub_memcpy((char *) nb->data + etherhdr_size - 6,
- (char *) nb->data + etherhdr_size - 2, 2);
- }
-
eth = (struct etherhdr *) nb->data;
- type = grub_be_to_cpu16 (eth->type);
- err = grub_netbuff_pull (nb, etherhdr_size);
+ err = grub_netbuff_pull (nb, sizeof (*eth));
if (err)
return err;
+ type = grub_be_to_cpu16 (eth->type);
+
+ /* Check if a vlan-tag is present. */
+ if (type == GRUB_NET_ETHERTYPE_802_1Q)
+ {
+ vlan = (struct vlanhdr *) nb->data;
+ err = grub_netbuff_pull (nb, sizeof (*vlan));
+ if (err)
+ return err;
+ vlantag = grub_be_to_cpu16 (vlan->vtag) & 0xfff;
+ type = grub_be_to_cpu16 (vlan->type);
+ }
if (type <= 1500)
{
@@ -157,14 +155,17 @@ 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);
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);
+ case GRUB_NET_ETHERTYPE_802_1Q:
+ /* pacify compiler */
+ break;
}
grub_netbuff_free (nb);
return GRUB_ERR_NONE;
diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c
index ffdc760..afa35ef 100644
--- a/grub-core/net/ip.c
+++ b/grub-core/net/ip.c
@@ -228,7 +228,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,
grub_uint8_t ttl)
{
struct grub_net_network_level_interface *inf = NULL;
@@ -274,6 +274,7 @@ handle_dgram (struct grub_net_buff *nb,
FOR_NET_NETWORK_LEVEL_INTERFACES (inf)
if (inf->card == card
+ && inf->vlantag == vlantag
&& inf->address.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV
&& inf->hwaddress.type == GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET
&& grub_memcmp (inf->hwaddress.mac, &bootp->mac_addr,
@@ -290,19 +291,15 @@ handle_dgram (struct grub_net_buff *nb,
FOR_NET_NETWORK_LEVEL_INTERFACES (inf)
{
+ /* Verify vlantag id */
+ if (inf->vlantag != vlantag)
+ continue;
+
if (inf->card == card
&& grub_net_addr_cmp (&inf->address, dest) == 0
&& grub_net_hwaddr_cmp (&inf->hwaddress, hwaddress) == 0)
break;
- /* Verify vlantag id */
- if (inf->card == card && inf->vlantag != *vlantag)
- {
- grub_dprintf ("net", "invalid vlantag! %x != %x\n",
- inf->vlantag, *vlantag);
- break;
- }
-
/* Solicited node multicast. */
if (inf->card == card
&& inf->address.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
@@ -392,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)
{
struct iphdr *iph = (struct iphdr *) nb->data;
grub_err_t err;
@@ -662,7 +659,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)
{
struct ip6hdr *iph = (struct ip6hdr *) nb->data;
grub_err_t err;
@@ -721,7 +718,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)
{
struct iphdr *iph = (struct iphdr *) nb->data;
diff --git a/grub-core/net/net.c b/grub-core/net/net.c
index 9424595..40125e1 100644
--- a/grub-core/net/net.c
+++ b/grub-core/net/net.c
@@ -1247,7 +1247,10 @@ 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)
+ grub_printf (" VID=%u", inf->vlantag);
+ grub_printf ("\n");
}
return GRUB_ERR_NONE;
}
diff --git a/include/grub/net.h b/include/grub/net.h
index 1096b24..20fb832 100644
--- a/include/grub/net.h
+++ b/include/grub/net.h
@@ -292,6 +292,7 @@ struct grub_net_network_level_interface
struct grub_net_bootp_packet *dhcp_ack;
grub_size_t dhcp_acklen;
grub_uint16_t vlantag;
+ grub_uint16_t prio;
void *data;
};
@@ -562,6 +563,4 @@ extern char *grub_net_default_server;
#define GRUB_NET_INTERVAL 400
#define GRUB_NET_INTERVAL_ADDITION 20
-#define VLANTAG_IDENTIFIER 0x8100
-
#endif /* ! GRUB_NET_HEADER */
diff --git a/include/grub/net/arp.h b/include/grub/net/arp.h
index 8d9d081..c82f3a2 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);
grub_err_t
grub_net_arp_send_request (struct grub_net_network_level_interface *inf,
diff --git a/include/grub/net/ethernet.h b/include/grub/net/ethernet.h
index 23a935e..78c5ebc 100644
--- a/include/grub/net/ethernet.h
+++ b/include/grub/net/ethernet.h
@@ -27,6 +27,7 @@ typedef enum
GRUB_NET_ETHERTYPE_IP = 0x0800,
GRUB_NET_ETHERTYPE_ARP = 0x0806,
GRUB_NET_ETHERTYPE_IP6 = 0x86DD,
+ GRUB_NET_ETHERTYPE_802_1Q = 0x8100,
} grub_net_ethertype_t;
grub_err_t
diff --git a/include/grub/net/ip.h b/include/grub/net/ip.h
index ab9d68f..de934bd 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);
grub_err_t
grub_net_send_ip_packet (struct grub_net_network_level_interface *inf,
--
tg: (b4fc7bc..) n/vlan-cleanup (depends on: next)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH] [next] net: VLAN cleanup,
Andrei Borzenkov <=