[ipxe-devel] [PATCH 0/2] [vlan] Support 802.1Q VLAN 0 priority tagging

Ladi Prosek lprosek at redhat.com
Thu Apr 21 12:48:22 UTC 2016


On Thu, Apr 21, 2016 at 12:18 PM, Michael Brown <mcb30 at ipxe.org> wrote:
> On 21/04/16 09:36, Ladi Prosek wrote:
>>
>> Following up on our IRC conversation, here's what I get when playing
>> with a Linux kernel with no VLAN support (!CONFIG_VLAN_8021Q &&
>> !CONFIG_VLAN_8021Q_MODULE).
>>
>> Receiving VLAN 0 packets works. The tag is stripped and the packet
>> passes through the networking stack as usual. Here's a VLAN 0 ping
>> request and response, 10.34.1.105 is running the VLAN-less kernel:
>>
>>    1   0.000000  10.34.1.136 -> 10.34.1.105  ICMP 50 Echo (ping)
>> request  id=0x03e8, seq=0/0, ttl=255
>>    2   0.000080  10.34.1.105 -> 10.34.1.136  ICMP 46 Echo (ping) reply
>>    id=0x03e8, seq=0/0, ttl=64 (request in 1)
>>
>> Note that the response is 4 bytes shorter because it doesn't have the
>> 802.1Q header.
>
>
> Fantastic; thank you for doing this testing.  I am suitably convinced that
> we ought to treat packets on VLAN 0 in the same way as packets with no VLAN
> tag.
>
> Unfortunately, this is going to be difficult to do.  Your patch handles
> packets that get processed by iPXE, but doesn't help with packets passed via
> the UNDI API.
>
> We do allow for a PXE NBP to use the UNDI API on a VLAN device.  Only the
> selected VLAN device gets frozen (via netdev_freeze()).  Packets arriving on
> the unfrozen trunk device are processed by iPXE as normal: the VLAN tag is
> stripped and the packet is requeued on the appropriately frozen VLAN device,
> whence pxenv_undi_isr() can dequeue it.
>
> This model breaks if we have to handle VLAN 0.  There is no separate VLAN
> device, so the trunk device itself will be frozen.  The packets will
> therefore end up being passed out directly via PXENV_UNDI_ISR; the VLAN tag
> will never be inspected or removed.  This will break most PXE NBPs.
>
> I can't immediately see a clean way to do this.  Potentially we would need
> to parse and strip the VLAN header at the point that netdev_rx() is called,
> instead of treating VLANs as a net_protocol.

Interesting, thanks. Why not strip it inside pxenv_undi_isr then? This
function already peeks into the network layer protocol so it doesn't
feel that unnatural to special case 802.1Q. Maybe without the goto :)
vlan_strip would be the guts of vlan_rx factored out to a separate
function doing pretty much everything except re-enquing the packet.

@@ -967,6 +968,7 @@ static PXENV_EXIT_t pxenv_undi_isr ( struct
s_PXENV_UNDI_ISR *undi_isr ) {

                /* Strip link-layer header */
                ll_protocol = pxe_netdev->ll_protocol;
+       strip_ll_header:
                if ( ( rc = ll_protocol->pull ( pxe_netdev, iobuf, &ll_dest,
                                                &ll_source, &net_proto,
                                                &flags ) ) != 0 ) {
@@ -978,6 +980,13 @@ static PXENV_EXIT_t pxenv_undi_isr ( struct
s_PXENV_UNDI_ISR *undi_isr ) {

                /* Determine network-layer protocol */
                switch ( net_proto ) {
+               case htons ( ETH_P_8021Q ):
+                       if ( ( rc = vlan_strip ( pxe_netdev, iobuf, &ll_dest,
+                                                &ll_source ) ) != 0 ) {
+                               undi_isr->Status = PXENV_STATUS_FAILURE;
+                               return PXENV_EXIT_FAILURE;
+                       }
+                       goto strip_ll_header;
                case htons ( ETH_P_IP ):
                        net_protocol = &ipv4_protocol;
                        prottype = P_IP;



More information about the ipxe-devel mailing list