new file mode 100644
@@ -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);
+}
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 <eldad@fogrefinery.com> --- net/lldp/lldp_output.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 net/lldp/lldp_output.c