[PATCH 5/8] LLDP: Output routines
From: Eldad Zack <hidden>
Date: 2012-06-25 18:28:54
Subsystem:
networking [general], the rest · Maintainers:
"David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
Handles the transmission of LLDPDUs. Gets the TLV list, allocates the sk_buff according to the space requirements of the TLV list, writes it to the sk_buff and if all goes well, sends it to the wire. Signed-off-by: Eldad Zack <redacted> --- net/lldp/lldp_output.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 net/lldp/lldp_output.c
diff --git a/net/lldp/lldp_output.c b/net/lldp/lldp_output.c
new file mode 100644
index 0000000..45e6293
--- /dev/null
+++ b/net/lldp/lldp_output.c@@ -0,0 +1,67 @@ +/* LLDP Link Layer Discovery Protocol impementation for Linux + * IEEE Std 802.1ab + * + * Author: Eldad Zack <eldad@fogrefinery.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/if_ether.h> +#include <linux/netdevice.h> +#include <linux/skbuff.h> +#include "lldp.h" + +static u8 lldp_dst_address[] = LLDP_MULTICAST_ADDR; + +inline struct sk_buff *lldp_create(struct net_device *dev, bool is_shutdown) +{ + struct sk_buff *skb; + struct list_head head; + int head_len = LL_RESERVED_SPACE(dev); + int tail_len = dev->needed_tailroom; + int lldp_len; + + INIT_LIST_HEAD(&head); + + lldp_tlv_construct_list(&head, dev, is_shutdown); + lldp_len = lldp_tlv_list_len(&head); + + skb = alloc_skb(head_len + lldp_len + tail_len, GFP_ATOMIC); + if (skb == NULL) + goto done; + + skb_reserve(skb, head_len); + skb_reset_network_header(skb); + + lldp_tlv_put_skb_list(skb, &head); + + skb->dev = dev; + skb->protocol = htons(ETH_P_LLDP); + + if (dev_hard_header(skb, dev, ETH_P_LLDP, lldp_dst_address, + dev->dev_addr, skb->len) < 0) { + kfree_skb(skb); + skb = NULL; + } + +done: + lldp_tlv_destruct_list(&head); + return skb; +} + +void __lldp_send(struct net_device *dev, bool is_shutdown) +{ + struct sk_buff *skb; + + skb = lldp_create(dev, is_shutdown); + + if (skb == NULL) + return; + + dev_queue_xmit(skb); +}
--
1.7.10