br_send_bpdu and br_log_state PATCH

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

 



Hi all,
1) I modified br_send_bpdu() function.
I use an hardware switch that need to add 4 bytes after the DA/SA MAC address. So it's a special header.
I used p->dev->hard_header() instead of llc_mac_hdr_init() which fills default ethernet header (14 bytes : DA+SA+Len/Type)
My bridge code is based on kernel 2.6.17.8

2) I also added ioctl to device in br_log_state to inform the network device driver that port state has changed. This is useful if you need to modify hardware registers.
I used this ID for ioctls : SIOCDEVPRIVATE + 16
Maybe it can be a good idea to define a standard ioctl for this ??


Code 1)

static void br_send_bpdu(struct net_bridge_port *p,
              const unsigned char *data, int length)
{
    struct sk_buff *skb;
    int extra_header_len = p->dev->hard_header_len - ETH_HLEN;

    if (!p->br->stp_enabled)
        return;

    skb = dev_alloc_skb(length+LLC_RESERVE+extra_header_len);
    if (!skb)
        return;

    // Reserve area for extra header info
    if (extra_header_len)
        skb_reserve(skb, extra_header_len);

    skb->dev = p->dev;
    skb->protocol = htons(ETH_P_802_2);

    skb_reserve(skb, LLC_RESERVE);
    memcpy(__skb_put(skb, length), data, length);

    llc_pdu_header_init(skb, LLC_PDU_TYPE_U, LLC_SAP_BSPAN,
                LLC_SAP_BSPAN, LLC_PDU_CMD);
    llc_pdu_init_as_ui_cmd(skb);

    // Check pointers and fill header
    if (p->dev!=NULL && p->dev->hard_header!=NULL && p->dev->hard_header_len!=ETH_HLEN)
    {   
        // LLC_RESERVE can be 3 or 4 bytes !
        p->dev->hard_header(skb, p->dev, ETH_P_802_3,
                            p->br->group_addr, p->dev->dev_addr, skb->len);
    }
    else
    {    // deafault ethernet header
        llc_mac_hdr_init(skb, p->dev->dev_addr, p->br->group_addr);
    }

    NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
        dev_queue_xmit);
}


Code 2
void br_log_state(const struct net_bridge_port *p)
{
    pr_info("%s: port %d(%s) entering %s state\n",
        p->br->dev->name, p->port_no, p->dev->name,
        br_port_state_names[p->state]);

    p->dev->do_ioctl(    p->dev,     // network device
                        (struct ifreq*)p,    // data (struct net_bridge)
                        SIOCDEVPRIVATE + 16);    // command ID
}
_______________________________________________
Bridge mailing list
Bridge@xxxxxxxxxxxxxxxxxxxxxxxxxx
https://lists.linux-foundation.org/mailman/listinfo/bridge

[Index of Archives]     [Netdev]     [AoE Tools]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]     [Video 4 Linux]

  Powered by Linux