]> git.proxmox.com Git - mirror_ovs.git/blobdiff - lib/ovs-lldp.c
ofp-util: Zero out padding bytes in ofputil_ipfix_stats_to_reply().
[mirror_ovs.git] / lib / ovs-lldp.c
index 3edaf429a99208261018cc637ca53860be21e72c..55fc2320312cec7aa04d2c9538bf64f502c63f28 100644 (file)
@@ -34,9 +34,9 @@
 #include <stdbool.h>
 #include <stdlib.h>
 #include <sys/types.h>
-#include "dynamic-string.h"
+#include "openvswitch/dynamic-string.h"
 #include "flow.h"
-#include "list.h"
+#include "openvswitch/list.h"
 #include "lldp/lldpd.h"
 #include "lldp/lldpd-structs.h"
 #include "netdev.h"
@@ -202,8 +202,10 @@ aa_print_element_status_port(struct ds *ds, struct lldpd_hardware *hw)
         if (memcmp(&port->p_element.system_id,
                    &system_id_null,
                    sizeof port->p_element.system_id)) {
-            static char *none_str = "<None>";
-            char *id = none_str, *descr = none_str, *system = none_str;
+            const char *none_str = "<None>";
+            const char *descr = NULL;
+            char *id = NULL;
+            char *system;
 
             if (port->p_chassis) {
                 if (port->p_chassis->c_id_len > 0) {
@@ -211,16 +213,16 @@ aa_print_element_status_port(struct ds *ds, struct lldpd_hardware *hw)
                                         port->p_chassis->c_id_len, &id);
                 }
 
-                descr = port->p_chassis->c_descr
-                    ? port->p_chassis->c_descr : none_str;
+                descr = port->p_chassis->c_descr;
             }
 
             chassisid_to_string((uint8_t *) &port->p_element.system_id,
                 sizeof port->p_element.system_id, &system);
 
-            ds_put_format(ds, "\tAuto Attach Primary Server Id: %s\n", id);
+            ds_put_format(ds, "\tAuto Attach Primary Server Id: %s\n",
+                          id ? id : none_str);
             ds_put_format(ds, "\tAuto Attach Primary Server Descr: %s\n",
-                          descr);
+                          descr ? descr : none_str);
             ds_put_format(ds, "\tAuto Attach Primary Server System Id: %s\n",
                           system);
 
@@ -255,7 +257,7 @@ aa_print_isid_status_port_isid(struct lldp *lldp, struct lldpd_port *port)
 {
     struct lldpd_aa_isid_vlan_maps_tlv *mapping;
 
-    if (list_is_empty(&port->p_isid_vlan_maps)) {
+    if (ovs_list_is_empty(&port->p_isid_vlan_maps)) {
         return;
     }
 
@@ -389,14 +391,12 @@ update_mapping_on_lldp(struct lldp *lldp, struct lldpd_hardware *hardware,
 {
     struct lldpd_aa_isid_vlan_maps_tlv *lm = xzalloc(sizeof *lm);
 
-    if (hardware->h_ifname) {
-        VLOG_INFO("\t\t hardware->h_ifname=%s", hardware->h_ifname);
-    }
+    VLOG_INFO("\t\t hardware->h_ifname=%s", hardware->h_ifname);
 
     lm->isid_vlan_data.isid = m->isid;
     lm->isid_vlan_data.vlan = m->vlan;
 
-    list_push_back(&hardware->h_lport.p_isid_vlan_maps, &lm->m_entries);
+    ovs_list_push_back(&hardware->h_lport.p_isid_vlan_maps, &lm->m_entries);
 
     /* TODO Should be done in the Auto Attach state machine when a mapping goes
      * from "pending" to "active".
@@ -407,7 +407,7 @@ update_mapping_on_lldp(struct lldp *lldp, struct lldpd_hardware *hardware,
     node->vlan = m->vlan;
     node->oper = BRIDGE_AA_VLAN_OPER_ADD;
 
-    list_push_back(&lldp->active_mapping_queue, &node->list_node);
+    ovs_list_push_back(&lldp->active_mapping_queue, &node->list_node);
 }
 
 /* Bridge will poll the list of VLAN that needs to be auto configure based on
@@ -431,7 +431,7 @@ aa_get_vlan_queued(struct ovs_list *list)
             copy->vlan = node->vlan;
             copy->oper = node->oper;
 
-            list_push_back(list, &copy->list_node);
+            ovs_list_push_back(list, &copy->list_node);
 
             /* Cleanup */
             free(node->port_name);
@@ -455,7 +455,7 @@ aa_get_vlan_queue_size(void)
     ovs_mutex_lock(&mutex);
 
     HMAP_FOR_EACH (lldp, hmap_node, all_lldps) {
-        size += list_size(&lldp->active_mapping_queue);
+        size += ovs_list_size(&lldp->active_mapping_queue);
     }
 
     ovs_mutex_unlock(&mutex);
@@ -570,7 +570,7 @@ aa_mapping_unregister_mapping(struct lldp *lldp,
                       isid,
                       lm->isid_vlan_data.vlan);
 
-            list_remove(&lm->m_entries);
+            ovs_list_remove(&lm->m_entries);
 
             /* TODO Should be done in the AA SM when a mapping goes
              * from "pending" to "active".
@@ -581,7 +581,7 @@ aa_mapping_unregister_mapping(struct lldp *lldp,
             node->vlan = m->vlan;
             node->oper = BRIDGE_AA_VLAN_OPER_REMOVE;
 
-            list_push_back(&lldp->active_mapping_queue, &node->list_node);
+            ovs_list_push_back(&lldp->active_mapping_queue, &node->list_node);
 
             break;
         }
@@ -617,16 +617,13 @@ aa_mapping_unregister(void *aux)
             }
 
             hmap_remove(&lldp->mappings_by_aux, &m->hmap_node_aux);
-            free(m);
 
             /* Remove from all the lldp instances */
             LIST_FOR_EACH (hw, h_entries, &lldp->lldpd->g_hardware) {
-                if (hw->h_ifname) {
-                    VLOG_INFO("\t\t hardware->h_ifname=%s", hw->h_ifname);
-                }
-
+                VLOG_INFO("\t\t hardware->h_ifname=%s", hw->h_ifname);
                 aa_mapping_unregister_mapping(lldp, hw, m);
             }
+            free(m);
 
             /* Remove from the all_mappings */
             HMAP_FOR_EACH (m, hmap_node_isid, all_mappings) {
@@ -658,9 +655,9 @@ lldp_init(void)
  * fields in 'wc' that were used to make the determination.
  */
 bool
-lldp_should_process_flow(const struct flow *flow)
+lldp_should_process_flow(struct lldp *lldp, const struct flow *flow)
 {
-    return (flow->dl_type == htons(ETH_TYPE_LLDP));
+    return (flow->dl_type == htons(ETH_TYPE_LLDP) && lldp->enabled);
 }
 
 
@@ -687,6 +684,9 @@ lldp_should_send_packet(struct lldp *cfg) OVS_EXCLUDED(mutex)
     ret = timer_expired(&cfg->tx_timer);
     ovs_mutex_unlock(&mutex);
 
+    /* LLDP must be enabled */
+    ret &= cfg->enabled;
+
     return ret;
 }
 
@@ -697,7 +697,7 @@ lldp_wake_time(const struct lldp *lldp) OVS_EXCLUDED(mutex)
 {
     long long int retval;
 
-    if (!lldp) {
+    if (!lldp || !lldp->enabled) {
         return LLONG_MAX;
     }
 
@@ -722,22 +722,18 @@ lldp_wait(struct lldp *lldp) OVS_EXCLUDED(mutex)
  */
 void
 lldp_put_packet(struct lldp *lldp, struct dp_packet *packet,
-                uint8_t eth_src[ETH_ADDR_LEN]) OVS_EXCLUDED(mutex)
+                const struct eth_addr eth_src) OVS_EXCLUDED(mutex)
 {
     struct lldpd *mylldpd = lldp->lldpd;
     struct lldpd_hardware *hw = lldpd_first_hardware(mylldpd);
-    uint32_t lldp_size = 0;
-    static const uint8_t eth_addr_lldp[6] =
-        {0x01, 0x80, 0xC2, 0x00, 0x00, 0x0e};
+    static const struct eth_addr eth_addr_lldp =
+        { { { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x0e } } };
 
     ovs_mutex_lock(&mutex);
 
     eth_compose(packet, eth_addr_lldp, eth_src, ETH_TYPE_LLDP, 0);
 
-    lldp_size = lldpd_send(hw, packet);
-    if (lldp_size + ETH_HEADER_LEN < MINIMUM_ETH_PACKET_SIZE) {
-        lldp_size = MINIMUM_ETH_PACKET_SIZE;
-    }
+    lldpd_send(hw, packet);
 
     timer_set_duration(&lldp->tx_timer, lldp->lldpd->g_config.c_tx_interval);
     ovs_mutex_unlock(&mutex);
@@ -746,9 +742,15 @@ lldp_put_packet(struct lldp *lldp, struct dp_packet *packet,
 /* Configures the LLDP stack.
  */
 bool
-lldp_configure(struct lldp *lldp) OVS_EXCLUDED(mutex)
+lldp_configure(struct lldp *lldp, const struct smap *cfg) OVS_EXCLUDED(mutex)
 {
     if (lldp) {
+        if (cfg && smap_get_bool(cfg, "enable", false)) {
+            lldp->enabled = true;
+        } else {
+            lldp->enabled = false;
+        }
+
         ovs_mutex_lock(&mutex);
         timer_set_expired(&lldp->tx_timer);
         timer_set_duration(&lldp->tx_timer, LLDP_DEFAULT_TRANSMIT_INTERVAL_MS);
@@ -782,23 +784,25 @@ lldp_create(const struct netdev *netdev,
 
     hmap_init(&lldp->mappings_by_isid);
     hmap_init(&lldp->mappings_by_aux);
-    list_init(&lldp->active_mapping_queue);
+    ovs_list_init(&lldp->active_mapping_queue);
 
     lchassis = xzalloc(sizeof *lchassis);
     lchassis->c_cap_available = LLDP_CAP_BRIDGE;
     lchassis->c_cap_enabled = LLDP_CAP_BRIDGE;
     lchassis->c_id_subtype = LLDP_CHASSISID_SUBTYPE_LLADDR;
     lchassis->c_id_len = ETH_ADDR_LEN;
-    lchassis->c_id = xmalloc(ETH_ADDR_LEN);
-    netdev_get_etheraddr(netdev, lchassis->c_id);
 
-    list_init(&lchassis->c_mgmt);
+    struct eth_addr *mac = xmalloc(ETH_ADDR_LEN);
+    netdev_get_etheraddr(netdev, mac);
+    lchassis->c_id = &mac->ea[0];
+
+    ovs_list_init(&lchassis->c_mgmt);
     lchassis->c_ttl = lldp->lldpd->g_config.c_tx_interval *
                       lldp->lldpd->g_config.c_tx_hold;
     lchassis->c_ttl = LLDP_CHASSIS_TTL;
     lldpd_assign_cfg_to_protocols(lldp->lldpd);
-    list_init(&lldp->lldpd->g_chassis);
-    list_push_back(&lldp->lldpd->g_chassis, &lchassis->list);
+    ovs_list_init(&lldp->lldpd->g_chassis);
+    ovs_list_push_back(&lldp->lldpd->g_chassis, &lchassis->list);
 
     if ((hw = lldpd_alloc_hardware(lldp->lldpd,
                                    (char *) netdev_get_name(netdev),
@@ -830,9 +834,9 @@ lldp_create(const struct netdev *netdev,
     hw->h_lport.p_element.system_id.rsvd2[0] = 0;
     hw->h_lport.p_element.system_id.rsvd2[1] = 0;
 
-    list_init(&hw->h_lport.p_isid_vlan_maps);
-    list_init(&lldp->lldpd->g_hardware);
-    list_push_back(&lldp->lldpd->g_hardware, &hw->h_entries);
+    ovs_list_init(&hw->h_lport.p_isid_vlan_maps);
+    ovs_list_init(&lldp->lldpd->g_hardware);
+    ovs_list_push_back(&lldp->lldpd->g_hardware, &hw->h_entries);
 
     ovs_mutex_lock(&mutex);
 
@@ -876,20 +880,19 @@ lldp_create_dummy(void)
 
     hmap_init(&lldp->mappings_by_isid);
     hmap_init(&lldp->mappings_by_aux);
-    list_init(&lldp->active_mapping_queue);
+    ovs_list_init(&lldp->active_mapping_queue);
 
     lchassis = xzalloc(sizeof *lchassis);
     lchassis->c_cap_available = LLDP_CAP_BRIDGE;
     lchassis->c_cap_enabled = LLDP_CAP_BRIDGE;
     lchassis->c_id_subtype = LLDP_CHASSISID_SUBTYPE_LLADDR;
     lchassis->c_id_len = ETH_ADDR_LEN;
-    lchassis->c_id = xmalloc(ETH_ADDR_LEN);
 
-    list_init(&lchassis->c_mgmt);
+    ovs_list_init(&lchassis->c_mgmt);
     lchassis->c_ttl = LLDP_CHASSIS_TTL;
     lldpd_assign_cfg_to_protocols(lldp->lldpd);
-    list_init(&lldp->lldpd->g_chassis);
-    list_push_back(&lldp->lldpd->g_chassis, &lchassis->list);
+    ovs_list_init(&lldp->lldpd->g_chassis);
+    ovs_list_push_back(&lldp->lldpd->g_chassis, &lchassis->list);
 
     hw = lldpd_alloc_hardware(lldp->lldpd, "dummy-hw", 0);
 
@@ -907,17 +910,15 @@ lldp_create_dummy(void)
     /* Auto Attach element tlv */
     hw->h_lport.p_element.type = LLDP_TLV_AA_ELEM_TYPE_CLIENT_VIRTUAL_SWITCH;
     hw->h_lport.p_element.mgmt_vlan = 0;
-    memcpy(&hw->h_lport.p_element.system_id.system_mac,
-           lchassis->c_id, lchassis->c_id_len);
     hw->h_lport.p_element.system_id.conn_type =
         LLDP_TLV_AA_ELEM_CONN_TYPE_SINGLE;
     hw->h_lport.p_element.system_id.rsvd = 0;
     hw->h_lport.p_element.system_id.rsvd2[0] = 0;
     hw->h_lport.p_element.system_id.rsvd2[1] = 0;
 
-    list_init(&hw->h_lport.p_isid_vlan_maps);
-    list_init(&lldp->lldpd->g_hardware);
-    list_push_back(&lldp->lldpd->g_hardware, &hw->h_entries);
+    ovs_list_init(&hw->h_lport.p_isid_vlan_maps);
+    ovs_list_init(&lldp->lldpd->g_hardware);
+    ovs_list_push_back(&lldp->lldpd->g_hardware, &hw->h_entries);
 
     return lldp;
 }
@@ -946,7 +947,7 @@ lldp_unref(struct lldp *lldp)
     free(lldp);
 }
 
-/* Unreference a specific LLDP instance.
+/* Reference a specific LLDP instance.
  */
 struct lldp *
 lldp_ref(const struct lldp *lldp_)
@@ -957,3 +958,32 @@ lldp_ref(const struct lldp *lldp_)
     }
     return lldp;
 }
+
+void
+lldp_destroy_dummy(struct lldp *lldp)
+{
+    struct lldpd_hardware *hw, *hw_next;
+    struct lldpd_chassis *chassis, *chassis_next;
+    struct lldpd *cfg;
+
+    if (!lldp) {
+        return;
+    }
+
+    cfg = lldp->lldpd;
+
+    LIST_FOR_EACH_SAFE (hw, hw_next, h_entries, &cfg->g_hardware) {
+        ovs_list_remove(&hw->h_entries);
+        free(hw->h_lport.p_lastframe);
+        free(hw);
+    }
+
+    LIST_FOR_EACH_SAFE (chassis, chassis_next, list, &cfg->g_chassis) {
+        ovs_list_remove(&chassis->list);
+        free(chassis);
+    }
+
+    free(lldp->lldpd);
+    free(lldp);
+}
+