]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
lldp: add sd_lldp_tlv_packet_get_destination_type()
authorBeniamino Galvani <bgalvani@redhat.com>
Mon, 27 Jul 2015 16:04:46 +0000 (18:04 +0200)
committerBeniamino Galvani <bgalvani@redhat.com>
Fri, 2 Oct 2015 15:39:22 +0000 (17:39 +0200)
It can be useful to know the destination address of a LLDP frame
because it determines the scope of propagation of the frame and thus
this information be used to know whether the neighbor is connected to
the same physical link.

See clause 7.1 of IEEE Std 802.1AB-2009.

src/libsystemd-network/lldp-tlv.c
src/libsystemd-network/lldp-tlv.h
src/libsystemd-network/test-lldp.c
src/systemd/sd-lldp.h

index 24f2606f31998ca87ac52b8aafbe18cc8841a039..996c5b8881f19149ba2a905592e95df32d7d5be3 100644 (file)
@@ -539,3 +539,20 @@ int sd_lldp_packet_read_system_capability(tlv_packet *tlv, uint16_t *data) {
 
         return r;
 }
+
+int sd_lldp_packet_get_destination_type(tlv_packet *tlv, int *dest) {
+        assert_return(tlv, -EINVAL);
+        assert_return(dest, -EINVAL);
+
+        /* 802.1AB-2009, Table 7-1 */
+        if (!memcmp(&tlv->mac, LLDP_MAC_NEAREST_BRIDGE, ETH_ALEN))
+                *dest = SD_LLDP_DESTINATION_TYPE_NEAREST_BRIDGE;
+        else if (!memcmp(&tlv->mac, LLDP_MAC_NEAREST_NON_TPMR_BRIDGE, ETH_ALEN))
+                *dest = SD_LLDP_DESTINATION_TYPE_NEAREST_NON_TPMR_BRIDGE;
+        else if (!memcmp(&tlv->mac, LLDP_MAC_NEAREST_CUSTOMER_BRIDGE, ETH_ALEN))
+                *dest = SD_LLDP_DESTINATION_TYPE_NEAREST_CUSTOMER_BRIDGE;
+        else
+                return -EINVAL;
+
+        return 0;
+}
index 19509d3589f507b09f1840817cc911a4509b08ee..5af06b40ca4a8887e35bcf2af93c073e04c893cc 100644 (file)
@@ -43,6 +43,10 @@ struct tlv_section {
         LIST_FIELDS(tlv_section, section);
 };
 
+#define LLDP_MAC_NEAREST_BRIDGE          (uint8_t[]) { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e }
+#define LLDP_MAC_NEAREST_NON_TPMR_BRIDGE (uint8_t[]) { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 }
+#define LLDP_MAC_NEAREST_CUSTOMER_BRIDGE (uint8_t[]) { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }
+
 int tlv_section_new(tlv_section **ret);
 void tlv_section_free(tlv_section *ret);
 
index 26f64347a74ffcf3aece6484eacebbbb39ae0d93..294198a0b5892dfeba52809a99fb537c9546bdc5 100644 (file)
@@ -202,6 +202,15 @@ static int lldp_parse_ttl_tlv(tlv_packet *m) {
         return 0;
 }
 
+static int lldp_get_destination_type(tlv_packet *m) {
+        int dest;
+
+        assert_se(sd_lldp_packet_get_destination_type(m, &dest) >= 0);
+        assert_se(dest == SD_LLDP_DESTINATION_TYPE_NEAREST_BRIDGE);
+
+        return 0;
+}
+
 static int lldp_parse_tlv_packet(tlv_packet *m, int len) {
         uint8_t subtype;
 
@@ -212,6 +221,8 @@ static int lldp_parse_tlv_packet(tlv_packet *m, int len) {
         assert_se(lldp_parse_ttl_tlv(m) >= 0);
         assert_se(lldp_parse_system_desc_tlv(m) >= 0);
 
+        assert_se(lldp_get_destination_type(m) >= 0);
+
         return 0;
 }
 
index e472cbece943f0ba9bd94555fd31cc99dac4dbe3..bf6dfc1ee0f3629cd327d2cbf6a44e33915312c4 100644 (file)
@@ -28,6 +28,12 @@ enum {
         SD_LLDP_EVENT_UPDATE_INFO       = 0,
 };
 
+enum {
+        SD_LLDP_DESTINATION_TYPE_NEAREST_BRIDGE,
+        SD_LLDP_DESTINATION_TYPE_NEAREST_NON_TPMR_BRIDGE,
+        SD_LLDP_DESTINATION_TYPE_NEAREST_CUSTOMER_BRIDGE,
+};
+
 typedef struct sd_lldp sd_lldp;
 typedef struct tlv_packet sd_lldp_packet;
 
@@ -56,4 +62,6 @@ int sd_lldp_packet_read_port_description(sd_lldp_packet *tlv, char **data, uint1
 sd_lldp_packet *sd_lldp_packet_ref(sd_lldp_packet *tlv);
 sd_lldp_packet *sd_lldp_packet_unref(sd_lldp_packet *tlv);
 
+int sd_lldp_packet_get_destination_type(sd_lldp_packet *tlv, int *dest);
+
 int sd_lldp_get_packets(sd_lldp *lldp, sd_lldp_packet ***tlvs);