diff --git a/src/1905_tlvs.h b/src/1905_tlvs.h index 7c3a4cc9576b8e86be7018aa1a5d192c6c903a9e..616815854e4b6442f1ad3a2dcf74f38db923f3c7 100644 --- a/src/1905_tlvs.h +++ b/src/1905_tlvs.h @@ -46,7 +46,7 @@ #define TLV_TYPE_LAST (30) -// Media types as detailed in "Table 6-12" +/* Media types */ #define MEDIA_TYPE_IEEE_802_3U_FAST_ETHERNET (0x0000) #define MEDIA_TYPE_IEEE_802_3AB_GIGABIT_ETHERNET (0x0001) #define MEDIA_TYPE_IEEE_802_11B_2_4_GHZ (0x0100) @@ -63,359 +63,249 @@ #define MEDIA_TYPE_UNKNOWN (0xFFFF) -// IEEE802.11 frequency bands used in "Tables 6-22 and 6-24" -#define IEEE80211_ROLE_REGISTRAR (0x00) -// IEEE802.11 frequency bands used in "Tables 6-23 and 6-25" +/* IEEE802.11 frequency bands */ #define IEEE80211_FREQUENCY_BAND_2_4_GHZ (0x00) #define IEEE80211_FREQUENCY_BAND_5_GHZ (0x01) #define IEEE80211_FREQUENCY_BAND_60_GHZ (0x02) -// Media type structures detailed in "Tables 6-12 and 6-13" -struct _ieee80211SpecificInformation { - uint8_t network_membership[6]; // BSSID - -#define IEEE80211_SPECIFIC_INFO_ROLE_AP (0x0) -#define IEEE80211_SPECIFIC_INFO_ROLE_NON_AP_NON_PCP_STA (0x4) -#define IEEE80211_SPECIFIC_INFO_ROLE_WIFI_P2P_CLIENT (0x8) -#define IEEE80211_SPECIFIC_INFO_ROLE_WIFI_P2P_GROUP_OWNER (0x9) -#define IEEE80211_SPECIFIC_INFO_ROLE_AD_PCP (0xa) - uint8_t role; // One of the values from above +/* IEEE80211 roles */ +#define IEEE80211_ROLE_REGISTRAR (0x00) - uint8_t ap_channel_band; // Hex value of dot11CurrentChannelBandwidth - // (see "IEEE P802.11ac/D3.0" for description) +#define IEEE80211_ROLE_AP (0x0) +#define IEEE80211_ROLE_STA (0x4) +#define IEEE80211_ROLE_P2P_CLIENT (0x8) +#define IEEE80211_ROLE_P2P_GO (0x9) +#define IEEE80211_ROLE_AD_PCP (0xa) - uint8_t ap_channel_center_frequency_index_1; - // Hex value of - // dot11CurrentChannelCenterFrequencyIndex1 - // (see "IEEE P802.11ac/D3.0" for description) - uint8_t ap_channel_center_frequency_index_2; - // Hex value of - // dot11CurrentChannelCenterFrequencyIndex2 - // (see "IEEE P802.11ac/D3.0" for description) -}; +typedef uint8_t macaddr_t[6]; -struct _ieee1901SpecificInformation { - uint8_t network_identifier[7]; // Network membership -}; -union _mediaSpecificData { - uint8_t dummy; // Empty placeholder - struct _ieee80211SpecificInformation ieee80211; - struct _ieee1901SpecificInformation ieee1901; +/* TLV: End of message */ +struct tlv_eom { }; -/* Generic phy common structure used in "Tables 6.29, 6.36 and 6.38" */ -struct _genericPhyCommonData { +/* TLV: Vendor specific info */ +struct tlv_vendor_specific { uint8_t oui[3]; - uint8_t variant_index; - uint8_t media_specific_bytes_nr; - uint8_t *media_specific_bytes; -}; - -/* End of message TLV ("Section 6.4.1") */ -struct endOfMessageTLV { -}; - -/* Vendor specific TLV ("Section 6.4.2") */ -struct vendorSpecificTLV { - uint8_t vendorOUI[3]; - uint16_t m_nr; - uint8_t *m; -}; + uint16_t num_bytes; + uint8_t bytes[]; +} __attribute__((packed)); -/* AL MAC address type TLV ("Section 6.4.3") */ -struct alMacAddressTypeTLV { - uint8_t al_mac_address[6]; -}; +/* TLV: AL mac-address */ +struct tlv_aladdr { + uint8_t macaddr[6]; +} __attribute__ ((packed)); -/* MAC address type TLV ("Section 6.4.4") */ -struct macAddressTypeTLV { - uint8_t mac_address[6]; -}; +/* TLV: mac-address */ +struct tlv_macaddr { + uint8_t macaddr[6]; +} __attribute__((packed)); -/* Device information type TLV ("Section 6.4.5") */ -struct _localInterfaceEntries { - uint8_t mac_address[6]; - uint16_t media_type; /* One of the MEDIA_TYPE_* values */ - uint8_t media_specific_data_size; - // Number of bytes in ensuing field - // Its value is '10' when 'media_type' is one - // of the valid MEDIA_TYPE_IEEE_802_11* - // values. - // Its value is '7' when 'media_type' is one - // of the valid MEDIA_TYPE_IEEE_1901* values. - - union _mediaSpecificData media_specific_data; - // Media specific data - // It will contain a IEEE80211 structure - // when 'media_type' is one of the valid - // MEDIA_TYPE_IEEE_802_11* values - // It will contain a IEE1905 structure - // when 'media_type' is one of the valid - // MEDIA_TYPE_IEEE_1901* values - // It will be empty in the rest of cases -}; -struct deviceInformationTypeTLV { - uint8_t al_mac_address[6]; - uint8_t local_interfaces_nr; - struct _localInterfaceEntries *local_interfaces; -}; +/* IEEE 802.11 media specific info */ +struct ieee80211_info { + uint8_t bssid[6]; + uint8_t role; + uint8_t ap_bandwidth; + uint8_t ap_channel_seg0_idx; + uint8_t ap_channel_seg1_idx; +} __attribute__ ((packed)); +/* IEEE 1901 media specific info */ +struct ieee1901_info { + uint8_t netid[7]; +} __attribute__((packed)); +struct local_interface { + uint8_t macaddr[6]; + uint16_t mediatype; /* One of the MEDIA_TYPE_* values */ + uint8_t sizeof_mediainfo; + uint8_t mediainfo[]; /* ieee80211_info, ieee1901_info etc. */ +}__attribute__((packed)); -/* Device bridging capability TLV associated structures ("Section 6.4.6") */ -struct _bridgingTupleMacEntries { - uint8_t mac_address[6]; // MAC address of a 1905 device's network - // interface that belongs to a bridging tuple -}; +/* TLV: device information */ +struct tlv_device_info { + uint8_t aladdr[6]; + uint8_t num_interface; + struct local_interface interface[]; +} __attribute__((packed)); -struct _bridgingTupleEntries { - uint8_t bridging_tuple_macs_nr; // Number of MAC addresses in this bridging - struct _bridgingTupleMacEntries *bridging_tuple_macs; - // List of 'mac_nr' elements, each one - // representing a MAC. All these MACs are - // bridged together. -}; -struct deviceBridgingCapabilityTLV { - uint8_t bridging_tuples_nr; - struct _bridgingTupleEntries *bridging_tuples; +struct device_bridge_tuple_macaddr { + uint8_t macaddr[6]; +} __attribute__ ((packed)); -}; +struct device_bridge_tuple { + uint8_t num_macaddrs; + struct device_bridge_tuple_macaddr addr[]; +} __attribute__ ((packed)); -/* Non-1905 neighbor device list TLV ("Section 6.4.8") */ -struct _non1905neighborEntries { - uint8_t mac_address[6]; -}; - -struct non1905NeighborDeviceListTLV { - uint8_t local_mac_address[6]; - uint8_t non_1905_neighbors_nr; - struct _non1905neighborEntries *non_1905_neighbors; -}; +/* TLV: Device bridging capability */ +struct tlv_device_bridge_caps { + uint8_t num_tuples; + struct device_bridge_tuple tuple[]; +} __attribute__((packed)); -/* Neighbor device TLV ("Section 6.4.9") */ -struct _neighborEntries { - uint8_t mac_address[6]; // AL MAC address of the 1905 neighbor - uint8_t bridge_flag; // "0" --> no IEEE 802.1 bridge exists - // "1" --> at least one IEEE 802.1 bridge - // exists between this device and the - // neighbor -}; -struct neighborDeviceListTLV { - uint8_t local_mac_address[6]; - uint8_t neighbors_nr; - struct _neighborEntries *neighbors; +struct non1905_neighbor { + uint8_t macaddr[6]; }; +/* TLV: non-1905 neighbor devices */ +struct tlv_non1905_neighbor { + uint8_t local_macaddr[6]; + uint8_t num_non1905_nbrs; + struct non1905_neighbor non1905_nbr[]; +} __attribute__((packed)); -/* Link metric query TLV ("Section 6.4.10") */ -struct linkMetricQueryTLV { -#define LINK_METRIC_QUERY_TLV_ALL_NEIGHBORS (0x00) -#define LINK_METRIC_QUERY_TLV_SPECIFIC_NEIGHBOR (0x01) - uint8_t destination; // One of the values from above - uint8_t specific_neighbor[6]; - -#define LINK_METRIC_QUERY_TLV_TX_LINK_METRICS_ONLY (0x00) -#define LINK_METRIC_QUERY_TLV_RX_LINK_METRICS_ONLY (0x01) -#define LINK_METRIC_QUERY_TLV_BOTH_TX_AND_RX_LINK_METRICS (0x02) - uint8_t link_metrics_type; -}; - -/* Transmitter link metric TLV ("Section 6.4.11") */ -struct _transmitterLinkMetricEntries { - uint8_t local_interface_address[6]; // MAC address of an interface in - // the receiving AL, which connects - // to an interface in the neighbor - // AL - uint8_t neighbor_interface_address[6]; // MAC addres of an interface in a - // neighbor AL, which connects to - // an interface in the receiving - // AL +struct i1905_neighbor { + uint8_t aladdr[6]; + uint8_t has_bridge; +} __attribute__((packed)); - uint16_t intf_type; // Underlaying network technology - // One of the MEDIA_TYPE_* values. +/* TLV: 1905 neighbor devices */ +struct tlv_1905neighbor { + uint8_t local_macaddr[6]; + uint8_t num_1905nbrs; + struct i1905_neighbor nbr[]; +} __attribute__((packed)); - uint8_t bridge_flag; // Indicates whether or not the 1905 link - // includes one or more IEEE 802.11 - // bridges - uint32_t packet_errors; // Estimated number of lost packets on the - // transmitting side of the link during - // the measurement period (5 seconds??) - uint32_t transmitted_packets; // Estimated number of packets transmitted - // on the same measurement period used to - // estimate 'packet_errors' +#define LINKMETRIC_QUERY_NEIGHBOR_ALL (0x00) +#define LINKMETRIC_QUERY_NEIGHBOR_SPECIFIC (0x01) - uint16_t mac_throughput_capacity; // The maximum MAC throughput of the link - // estimated at the transmitter and - // expressed in Mb/s +#define LINKMETRIC_QUERY_TYPE_TX (0x00) +#define LINKMETRIC_QUERY_TYPE_RX (0x01) +#define LINKMETRIC_QUERY_TYPE_BOTH (0x02) - uint16_t link_availability; // The estimated average percentage of - // time that the link is available for - // data transmissions - - uint16_t phy_rate; // This value is the PHY rate estimated at - // the transmitter of the link expressed - // in Mb/s +/* TLV: link metric query */ +struct tlv_linkmetric_query { + uint8_t nbr_type; + uint8_t nbr_macaddr[6]; + uint8_t query_type; }; -struct transmitterLinkMetricTLV { - uint8_t tlv_type; // Must always be set to - // TLV_TYPE_TRANSMITTER_LINK_METRIC +struct tx_link_info { + uint8_t local_macaddr[6]; + uint8_t neighbor_macaddr[6]; + uint16_t mediatype; /* one of MEDIA_TYPE_* */ + uint8_t has_bridge; + uint32_t errors; + uint32_t packets; + uint16_t max_throughput; /* estimated mac thput in Mbps */ + uint16_t availability; /* in %age */ + uint16_t phyrate; /* estimated phy rate in Mbps */ +} __attribute__((packed)); - uint8_t local_al_address[6]; // AL MAC address of the device that - // transmits the response message that - // contains this TLV +/* TLV: transmitter link metric */ +struct tlv_tx_linkmetric { + uint8_t aladdr[6]; + uint8_t neighbor_aladdr[6]; + + uint8_t num_tx_links; + struct tx_link_info link[]; +} __attribute__((packed)); - uint8_t neighbor_al_address[6]; // AL MAC address of the neighbor whose - // link metric is reported in this TLV - uint8_t transmitter_link_metrics_nr; - struct _transmitterLinkMetricEntries *transmitter_link_metrics; - // Link metric information for the above - // interface pair between the receiving AL - // and the neighbor AL -}; -//////////////////////////////////////////////////////////////////////////////// -// Receiver link metric TLV associated structures ("Section 6.4.12") -//////////////////////////////////////////////////////////////////////////////// -struct _receiverLinkMetricEntries { - uint8_t local_interface_address[6]; // MAC address of an interface in - // the receiving AL, which connects - // to an interface in the neighbor - // AL - - uint8_t neighbor_interface_address[6]; // MAC addres of an interface in a - // neighbor AL, which connects to - // an interface in the receiving - // AL - - uint16_t intf_type; // Underlaying network technology - - uint32_t packet_errors; // Estimated number of lost packets on the - // receiving side of the link during - // the measurement period (5 seconds??) - - uint32_t packets_received; // Estimated number of packets received on - // the same measurement period used to - // estimate 'packet_errors' - - uint8_t rssi; // This value is the estimated RSSI at the - // receive side of the link expressed in - // dB -}; +struct rx_link_info { + uint8_t local_macaddr[6]; + uint8_t neighbor_macaddr[6]; + uint16_t mediatype; + uint32_t errors; + uint32_t packets; + int8_t rssi; /* in dBm */ +} __attribute__((packed)); +/* TLV: receiver link metric */ struct receiverLinkMetricTLV { - uint8_t tlv_type; // Must always be set to - // TLV_TYPE_RECEIVER_LINK_METRIC + uint8_t aladdr[6]; + uint8_t neighbor_aladdr[6]; + uint8_t num_rx_links; + struct rx_link_info link[]; +} __attribute__((packed)); - uint8_t local_al_address[6]; // AL MAC address of the device that - // transmits the response message that - // contains this TLV - uint8_t neighbor_al_address[6]; // AL MAC address of the neighbor whose - // link metric is reported in this TLV +#define LINKMETRIC_RESULT_INVALID_NEIGHBOR (0x00) - uint8_t receiver_link_metrics_nr; - struct _receiverLinkMetricEntries *receiver_link_metrics; - // Link metric information for the above - // interface pair between the receiving AL - // and the neighbor AL -}; +/* TLV: link metric result code */ +struct tlv_linkmetric_result { + uint8_t code; +} __attribute__((packed)); -//////////////////////////////////////////////////////////////////////////////// -// Link metric result code TLV associated structures ("Section 6.4.13") -//////////////////////////////////////////////////////////////////////////////// -struct linkMetricResultCodeTLV { - uint8_t tlv_type; // Must always be set to - // TLV_TYPE_LINK_METRIC_RESULT_CODE +/* TLV: searched role */ +struct tlv_searched_role { + uint8_t role; /* one of IEEE80211_ROLE_* */ +} __attribute__((packed)); -#define LINK_METRIC_RESULT_CODE_TLV_INVALID_NEIGHBOR (0x00) - uint8_t result_code; // One of the values from above -}; +/* TLV: autoconfig frequency band */ +struct tlv_autoconfig_band { + uint8_t band; /* one of IEEE80211_FREQUENCY_BAND_* */ +} __attribute__((packed)); -// Searched role TLV ("Section 6.4.14") -struct searchedRoleTLV { - uint8_t role; // One of IEEE80211_ROLE_* -}; +/* TLV: supported role */ +struct tlv_supported_role { + uint8_t role; /* one of IEEE80211_ROLE_* */ +} __attribute__((packed)); -// Autoconfig frequency band TLV ("Section 6.4.15") -struct autoconfigFreqBandTLV { - uint8_t freq_band; // one of IEEE80211_FREQUENCY_BAND_* -}; +/* TLV: supported frequency band */ +struct tlv_supported_band { + uint8_t band; /* one of IEEE80211_FREQUENCY_BAND_* */ +} __attribute__((packed)); -// Supported role TLV ("Section 6.4.16") -struct supportedRoleTLV { - uint8_t role; // One of IEEE80211_ROLE_* -}; -// Supported frequency band TLV ("Section 6.4.17") -struct supportedFreqBandTLV { - uint8_t freq_band; // one of IEEE80211_FREQUENCY_BAND_* -}; +/* TLV: wsc */ +struct tlv_wsc { + uint16_t framelen; + uint8_t frame[]; +} __attribute__((packed)); -// Supported frequency band TLV ("Section 6.4.18") -struct wscTLV { - uint16_t wsc_frame_size; - uint8_t *wsc_frame; -}; +struct media_info { + uint16_t type; + uint8_t sizeof_info; + uint8_t info[]; /* ieee80211_info, ieee1901_info etc. */ +} __attribute__((packed)); -// Push button event notification TLV ("Section 6.4.19") -struct _mediaTypeEntries { - uint16_t media_type; // One of the MEDIA_TYPE_* values - - uint8_t media_specific_data_size; - union _mediaSpecificData media_specific_data; - // Media specific data - // It will contain a IEEE80211 structure - // when 'media_type' is one of the valid - // MEDIA_TYPE_IEEE_802_11* values - // It will contain a IEE1905 structure - // when 'media_type' is one of the valid - // MEDIA_TYPE_IEEE_1901* values - // It will be empty in the rest of cases -}; +/* TLV: push button event notification */ +struct tlv_pbc_notification { + uint8_t num_media; + struct media_info media[]; +} __attribute__((packed)); -struct pushButtonEventNotificationTLV { - uint8_t media_types_nr; - struct _mediaTypeEntries *media_types; -}; +/* TLV: push button join notification */ +struct tlv_pbc_join_notification { + uint8_t aladdr[6]; + uint16_t mid; + uint8_t macaddr[6]; + uint8_t new_macaddr[6]; +} __attribute__((packed)); -// Push button join notification TLV ("Section 6.4.20") -struct pushButtonJoinNotificationTLV { - uint8_t al_mac_address[6]; - uint16_t message_identifier; // The message identifier (MID) of the push - // button event notification message - uint8_t mac_address[6]; // Interface specific MAC address of the - // interface of the transmitting device - // belonging to the medium on which a new - // device joined - uint8_t new_mac_address[6]; // Interface specific MAC address of the - // interface of the new device that was joined - // to the network as a result of the push - // button configuration sequence -}; //////////////////////////////////////////////////////////////////////////////// // Generic PHY device information TLV associated structures ("Section 6.4.21") //////////////////////////////////////////////////////////////////////////////// +// +/* Generic phy common structure used in "Tables 6.29, 6.36 and 6.38" */ +struct _genericPhyCommonData { + uint8_t oui[3]; + uint8_t variant_index; + uint8_t media_specific_bytes_nr; + uint8_t *media_specific_bytes; +}; + struct _genericPhyDeviceEntries { uint8_t local_interface_address[6]; // MAC address of the local interface diff --git a/src/cmdu_input.c b/src/cmdu_input.c index 208d39553f07da1debf224c6d9da795948e0b4b9..58d17f407161e63755202871dc602250aecfd424 100644 --- a/src/cmdu_input.c +++ b/src/cmdu_input.c @@ -41,7 +41,7 @@ // TODO: combine 3 following headers into one #include "1905_defs.h" -#include "i1905_tlvs.h" +#include "1905_tlvs.h" #include "lldp_tlvs.h" @@ -72,16 +72,18 @@ int i1905_handle_topology_discovery(struct i1905_interface_private *pif, if (hwaddr_is_zero(macaddr_origin)) { - fprintf(stderr, "%s: Discard topo discovery from src = 0!\n", + fprintf(stderr, + "%s: Discard topo discovery from src = 0!\n", __func__); return -1; } - ret = i1905_dm_neighour_update(i1905_interface_priv(pif), + ret = i1905_dm_neighbor_discovered(i1905_interface_priv(pif), aladdr_origin, macaddr_origin); if (ret) { - fprintf(stderr, "%s: Error updating DM for neighbor " MACFMT"\n", + fprintf(stderr, + "%s: Error updating DM for discovered neighbor " MACFMT"\n", __func__, MAC2STR(macaddr_origin)); return -1; @@ -108,16 +110,18 @@ int i1905_handle_topology_notification(struct i1905_interface_private *pif, if (hwaddr_is_zero(aladdr_origin)) { - fprintf(stderr, "%s: Discard topo notification from aladdr = 0!\n", + fprintf(stderr, + "%s: Discard topo notification from aladdr = 0!\n", __func__); return -1; } - ret = i1905_dm_neighour_update(i1905_interface_priv(pif), - aladdr_origin, NULL); + ret = i1905_dm_neighbor_changed(i1905_interface_priv(pif), + aladdr_origin); if (ret) { - fprintf(stderr, "%s: Error updating DM for neighbor " MACFMT"\n", + fprintf(stderr, + "%s: Error handling neighbor " MACFMT" change notification\n", __func__, MAC2STR(aladdr_origin)); return -1; @@ -146,31 +150,61 @@ int i1905_handle_topology_response(struct i1905_interface_private *pif, }; struct tlv *tv[6][16]; uint8_t aladdr_origin[6] = {0}; - uint8_t macaddr_origin[6] = {0}; int ret; cmdu_parse_tlvs(rxf, tv, a_policy, 6); -#if 0 - if (hwaddr_is_zero(macaddr_origin)) { - fprintf(stderr, "%s: Discard topo discovery from src = 0!\n", - __func__); + if (tv[0][0]) { + struct tlv_device_info *devinfo = + (struct tlv_device_info *)tv[0][0]->data; - return -1; + if (hwaddr_is_zero(devinfo->aladdr)) { + fprintf(stderr, "%s: Discard topo response from aladdr = 0!\n", + __func__); + + return -1; + } } - ret = i1905_dm_neighour_update(i1905_interface_priv(pif), - aladdr_origin, macaddr_origin); - if (ret) { - fprintf(stderr, "%s: Error updating DM for neighbor " MACFMT"\n", - __func__, MAC2STR(macaddr_origin)); + if (tv[1][0]) { + int num = 0; - return -1; + while (tv[1][num]) { + struct tlv_device_bridge_caps *brcaps = + (struct tlv_device_bridge_caps *)tv[1][num]->data; + + //i1905_dm_neighbor_update(pif, ); //TODO + num++; + } + } + + if (tv[2][0]) { + int num = 0; + + while (tv[2][num]) { + struct tlv_non1905_neighbor *non1905 = + (struct tlv_non1905_neighbor *)tv[2][num]->data; + + //i1905_dm_neighbor_update(pif, ); //TODO + num++; + } + } + + if (tv[3][0]) { + int num = 0; + + while (tv[3][num]) { + struct tlv_1905neighbor *nbrs = + (struct tlv_1905neighbor *)tv[3][num]->data; + + //i1905_dm_neighbor_update(pif, ); //TODO + num++; + } } -#endif + //TODO: tv[4], tv[5] return 0; } @@ -317,7 +351,7 @@ int i1905_process_cmdu(struct i1905_interface_private *pif, struct cmdu_buff *rx // TODO: discard duplicates - type = buf_get_be16(rxf->cdata->hdr.type); + type = buf_get_be16((uint8_t *)&rxf->cdata->hdr.type); if (i1905ftable[type]) { ret = i1905ftable[type](pif, rxf); diff --git a/src/i1905.c b/src/i1905.c index 2407270434e903cece8c4fd81fadca87e46547d1..c1b3f5b2541341b41c0e0a5f3835f6975cf38a7a 100644 --- a/src/i1905.c +++ b/src/i1905.c @@ -567,21 +567,27 @@ static int i1905_init_interfaces(struct i1905_private *p) sizeof(struct i1905_interface_private)); if (iface) { i1905_init_interface(iface, i1905_setup_interface_priv); + iface->device = &p->dm.self; memcpy(iface->aladdr, cfg->macaddr, 6); fprintf(stderr, "%s: aladdr = " MACFMT "\n", __func__, MAC2STR(cfg->macaddr)); - list_add_tail(&iface->list, &p->iflist); + list_add_tail(&iface->list, &p->dm.self.iflist); } } return 0; } - -static int i1905_init_al() +static int i1905_init_al(struct i1905_private *p) { - return 0; + int ret; + + i1905_dm_init(&p->dm); + + ret = i1905_init_interfaces(p); + + return ret; } void heartbeat_timer_cb(atimer_t *t) @@ -595,7 +601,8 @@ int i1905_run_bridge_discovery(struct i1905_private *p) { struct i1905_interface *iface; - list_for_each_entry(iface, &p->iflist, list) { + + list_for_each_entry(iface, &p->dm.self.iflist, list) { struct cmdu_buff *frm = NULL; uint8_t *lldpbuf; int ret = 0; @@ -685,7 +692,8 @@ int i1905_run_topology_discovery(struct i1905_private *p) { struct i1905_interface *iface; - list_for_each_entry(iface, &p->iflist, list) { + + list_for_each_entry(iface, &p->dm.self.iflist, list) { struct cmdu_buff *frm = NULL; struct tlv *t; int ret = 0; @@ -781,7 +789,6 @@ int i1905_init(void **priv, void *cfg) return -1; - INIT_LIST_HEAD(&p->iflist); INIT_LIST_HEAD(&p->extlist); p->ctx = ubus_connect(NULL); @@ -800,7 +807,7 @@ int i1905_init(void **priv, void *cfg) __func__, p, p->cfg.registrar_2g, p->cfg.registrar_5g); - ret = i1905_init_interfaces(p); + ret = i1905_init_al(p); if (ret) goto out_err; diff --git a/src/i1905.h b/src/i1905.h index d12e372fbf608a12053a7cc934c73a675ffb8eb0..e73c2de760a86baac0c5c0e1e9c82ff6edf3b8e4 100644 --- a/src/i1905.h +++ b/src/i1905.h @@ -14,6 +14,7 @@ struct i1905_private { atimer_t topotimer; struct list_head extlist; struct list_head iflist; + struct i1905_dm dm; struct ubus_context *ctx; struct ubus_object obj; @@ -29,7 +30,7 @@ struct i1905_interface_private { struct cmdu_queue rxqueue; struct worker rxwork; - void *iface; + void *iface; /* points to i1905_interface */ struct ubus_object obj; struct ubus_object_type obj_type; }; @@ -71,7 +72,14 @@ extern struct i1905_dm *i1905_dm_get(); extern int i1905_dm_init(struct i1905_dm *dm); extern int i1905_dm_free(struct i1905_dm *dm); +extern int i1905_dm_neighour_discovered(struct i1905_interface *iface, + uint8_t *aladdr, uint8_t *macaddr); + + +extern int i1905_dm_neighour_changed(struct i1905_interface *iface, + uint8_t *aladdr); + extern int i1905_dm_neighour_update(struct i1905_interface *iface, - uint8_t *aladdr, uint8_t *macaddr); + uint8_t *aladdr, struct tlv *t); #endif /* I1905_H */ diff --git a/src/i1905_dm.c b/src/i1905_dm.c index b8951e7c06d6a6f52adcb9be60977ad17f039e51..02c782ecf19f8fc5b78e950b45c7fe8e4f45bd60 100644 --- a/src/i1905_dm.c +++ b/src/i1905_dm.c @@ -23,36 +23,220 @@ #include <libubox/utils.h> #include <libubus.h> +#include <easy/easy.h> #include "cmdu.h" #include "i1905_dm.h" +#include "1905_defs.h" +#include "i1905_tlvs.h" +#include "lldp_tlvs.h" -int i1905_dm_neighour_update(struct i1905_interface *iface, uint8_t *aladdr, - uint8_t *macaddr) +struct i1905_interface *i1905_dm_neighbor_interface_create(void) { + struct i1905_interface *rif; - //TODO: lookup aladdr/macaddr in DM - // if not available, add to DM - // if available, update tsp - // - // if tsp_lastupdated = 0 or > 10 secs, send topo query + rif = calloc(1, sizeof(*rif)); + if (!rif) { + fprintf(stderr, "-ENOMEM\n"); + return NULL; + } + + INIT_LIST_HEAD(&rif->vendorlist); + INIT_LIST_HEAD(&rif->nbrlist); + INIT_LIST_HEAD(&rif->iflinklist); + + return rif; +} + +struct i1905_device *i1905_dm_neighbor_create(void) +{ + struct i1905_device *rdev; + + rdev = calloc(1, sizeof(*rdev)); + if (!rdev) { + fprintf(stderr, "-ENOMEM\n"); + return NULL; + } + + INIT_LIST_HEAD(&rdev->ipv4list); + INIT_LIST_HEAD(&rdev->ipv6list); + INIT_LIST_HEAD(&rdev->vendorlist); + INIT_LIST_HEAD(&rdev->iflist); + INIT_LIST_HEAD(&rdev->non1905_nbrlist); + INIT_LIST_HEAD(&rdev->nbrlist); + INIT_LIST_HEAD(&rdev->l2_nbrlist); + INIT_LIST_HEAD(&rdev->brlist); + INIT_LIST_HEAD(&rdev->reglist); + + return rdev; +} + + +struct i1905_device *i1905_dm_neighbor_lookup(struct i1905_interface *iface, + uint8_t *aladdr) +{ + struct i1905_selfdevice *self = (struct i1905_selfdevice *)iface->device; + struct i1905_device *rdev = NULL; + + //TODO: improve lookup + + list_for_each_entry(rdev, &self->topology.devlist, list) { + if (hwaddr_equal(rdev->aladdr, aladdr)) + break; + } + + return rdev; +} + +int i1905_dm_neighbor_update(struct i1905_interface *iface, uint8_t *aladdr, + struct tlv *t) +{ + struct i1905_selfdevice *self = (struct i1905_selfdevice *)iface->device; + struct i1905_interface *rif = NULL; + struct i1905_device *rdev = NULL; + int origin = 0; + int found = 0; + int ret; + + rdev = i1905_dm_neighbor_lookup(iface, aladdr); + if (!rdev) { + fprintf(stderr, "ALERT! received topo response without request!\n"); + return -1; + } + + switch (t->type) { + case TLV_TYPE_DEVICE_INFORMATION_TYPE: + break; + case TLV_TYPE_DEVICE_BRIDGING_CAPABILITIES: + break; + case TLV_TYPE_NON_1905_NEIGHBOR_DEVICE_LIST: + break; + case TLV_TYPE_NEIGHBOR_DEVICE_LIST: + break; + case TLV_TYPE_POWER_OFF_INTERFACE: + break; + case TLV_TYPE_L2_NEIGHBOR_DEVICE: + break; + default: + fprintf(stderr, "%s: Unhandled TLV %d\n", __func__, t->type); + break; + } + + return 0; +} + +int i1905_dm_neighbor_discovered(struct i1905_interface *iface, uint8_t *aladdr, + uint8_t *macaddr) +{ + struct i1905_selfdevice *self = (struct i1905_selfdevice *)iface->device; + struct i1905_interface *rif = NULL; + struct i1905_device *rdev = NULL; + + + + /* This function looksup neighbor device in DM. + * If present, then updates tsp. + * Moreover, if last-updated-tsp = 0 or > 10s, sends topo query. + */ + + rdev = i1905_dm_neighbor_lookup(iface, aladdr); + if (!rdev) { + rdev = i1905_dm_neighbor_create(); + if (!rdev) { + fprintf(stderr, "%s: failed to create nbr-device\n", __func__); + return -1; + } + + memcpy(rdev->aladdr, aladdr, 6); + list_add_tail(&rdev->list, &self->topology.devlist); + } + + //TODO: update timestamp of rdev + + /* record macaddr of origin interface if not already done */ + if (macaddr && !hwaddr_equal(aladdr, macaddr)) { + + list_for_each_entry(rif, &rdev->iflist, list) { + if (hwaddr_equal(rif->macaddr, macaddr)) { + /* nothing to do; origin is already known */ + return 0; + } + } + + rif = i1905_dm_neighbor_interface_create(); + if (!rif) { + fprintf(stderr, "%s: failed to create nbr-iface\n", __func__); + return -1; + } + + memcpy(rif->macaddr, macaddr, 6); + memcpy(rif->aladdr, aladdr, 6); + rif->device = rdev; + rif->priv = NULL; + + list_add_tail(&rif->list, &rdev->iflist); + } + + return 0; +} + +int i1905_dm_neighbor_changed(struct i1905_interface *iface, uint8_t *aladdr) +{ + struct i1905_selfdevice *self = (struct i1905_selfdevice *)iface->device; + struct i1905_device *rdev = NULL; + + + /* This function looksup neighbor device in DM. + * If present, then updates tsp and flag 'changed'. + * Moreover, it sends topo query to know what changed. + */ + + rdev = i1905_dm_neighbor_lookup(iface, aladdr); + if (!rdev) { + rdev = i1905_dm_neighbor_create(); + if (!rdev) { + fprintf(stderr, + "%s: failed to create nbr-device\n", __func__); + return -1; + } + + memcpy(rdev->aladdr, aladdr, 6); + list_add_tail(&rdev->list, &self->topology.devlist); + } + + //TODO: update timestamp of rdev + rdev->changed = true; + + //TODO: send topo query return 0; } int i1905_dm_init(struct i1905_dm *dm) { + struct i1905_selfdevice *self = &dm->self; + + memset(self, 0, sizeof(*self)); + + self->version = I1905_VERSION_DOT_1A; + self->regband = I1905_REGISTRAR_NONE; + self->num_interface = 0; + INIT_LIST_HEAD(&self->iflist); + + self->fwd.allow = true; + INIT_LIST_HEAD(&self->fwd.rulelist); - memset(dm->macaddr, 0, 6); + self->topology.enable = 0; + self->topology.status = 0; + self->topology.num_devices = 0; + INIT_LIST_HEAD(&self->topology.devlist); - INIT_LIST_HEAD(&dm->reglist); - INIT_LIST_HEAD(&dm->iflist); - INIT_LIST_HEAD(&dm->devlist); + self->security.method = I1905_SECURITY_PBC; - INIT_LIST_HEAD(&dm->fwd.rulelist); + INIT_LIST_HEAD(&self->reglist); return 0; } diff --git a/src/i1905_dm.h b/src/i1905_dm.h index 0c9b5c702caf8e420a395eb3a71931251b592186..55b5b2c857d542bd8de3893247a92d0e9caaf015 100644 --- a/src/i1905_dm.h +++ b/src/i1905_dm.h @@ -6,6 +6,9 @@ #include <stdint.h> #include <stdbool.h> +#include <netinet/in.h> +#include <arpa/inet.h> + enum i1905_version { I1905_VERSION_DOT_1, @@ -14,15 +17,17 @@ enum i1905_version { }; enum i1905_registrar_type { - I1905_REGISTRAR_2G, - I1905_REGISTRAR_5G, - I1905_REGISTRAR_60G, + I1905_REGISTRAR_NONE, + I1905_REGISTRAR_2G = 1 << 0, + I1905_REGISTRAR_5G = 1 << 1, + I1905_REGISTRAR_60G = 1 << 2, - _I1905_REGISTRAR_MAX, - I1905_NUM_REGISTRAR = _I1905_REGISTRAR_MAX, + //_I1905_REGISTRAR_MAX, + //I1905_NUM_REGISTRAR = _I1905_REGISTRAR_MAX, }; enum i1905_security_method { + I1905_SECURITY_UNKNOWN, I1905_SECURITY_UCPK, I1905_SECURITY_PBC, I1905_SECURITY_NFC, @@ -52,7 +57,7 @@ struct i1905_rinterface { struct list_head list; }; -struct i1905_neighbor { +struct i1905_net_neighbor { uint8_t macaddr[6]; uint8_t num_ifaces; struct list_head riflist; /* list of struct i1905_rinterface */ @@ -143,29 +148,75 @@ struct i1905_interface { uint8_t macaddr[6]; uint8_t aladdr[6]; /* FIXME: or have i1905_device ptr? */ uint32_t ifstatus; + void *device; /* points to device it belongs */ + enum i1905_mediatype media; /* media type */ + uint8_t *mediainfo; /* ieee80211_info, ieee1901_info etc. */ + struct i1905_genphy genphy; + bool allow_ifpower; /* allow set power state ? */ enum i1905_ifpowerstate power; + uint32_t num_vendor; struct list_head vendorlist; /* list of vendor properties */ + + uint32_t num_links; struct list_head iflinklist; /* list of interface links */ - struct list_head nbrlist; /* list of struct i1905_neighbor */ + + + struct list_head nbrlist; /* TODO: needed ? */ + struct list_head list; void *priv; /* interface private data */ }; - struct i1905_security { - //enum i1905_sectype method; //TODO + enum i1905_security_method method; uint8_t password[64]; }; -struct i1905_device { - //uint32_t tsp; + +enum ip4addr_type { + IP4_TYPE_UNKNOWN, + IP4_TYPE_DHCP, + IP4_TYPE_STATIC, + IP4_TYPE_AUTOIP, +}; + +struct i1905_ipv4 { + uint8_t macaddr[6]; + struct in_addr addr; + enum ip4addr_type type; + struct in_addr dhcpserver; + struct list_head list; +}; + +enum ip6addr_type { + IP6_TYPE_UNKNOWN, + IP6_TYPE_LINKLOCAL, + IP6_TYPE_DHCP, + IP6_TYPE_STATIC, + IP6_TYPE_SLAAC, +}; + +struct i1905_ipv6 { uint8_t macaddr[6]; + struct in6_addr addr; + enum ip6addr_type type; + struct in6_addr origin; + struct list_head list; +}; + +/* represents another 1905 device in the network */ +struct i1905_device { + uint32_t tsp; + bool changed; /* flag topo change notification */ + bool enabled; + uint8_t aladdr[6]; /* AL macaddress */ enum i1905_version version; - struct list_head reglist; /* list of struct i1905_registrar */ + uint8_t regband; /* bitmap of i1905_registrar_type */ + char name[128]; /* friendly name */ char manufacturer[128]; char model[128]; @@ -180,21 +231,52 @@ struct i1905_device { uint32_t num_neighbor_l2; uint32_t num_brtuple; - //TODO ptrs to structs + struct list_head ipv4list; /* list of i1905_ipv4 */ + struct list_head ipv6list; /* list of i1905_ipv6 */ + struct list_head vendorlist; /* list of i1905_vendor_info */ + struct list_head iflist; /* list of i1905_interface */ + struct list_head non1905_nbrlist; + struct list_head nbrlist; /* list of struct i1905_net_neighbor */ + struct list_head l2_nbrlist; + struct list_head brlist; /* list of */ - struct i1905_security security; // FIXME: needed ? + struct i1905_security security; + struct list_head reglist; /* list of i1905_registrar in network */ + + struct list_head list; }; -/* 1905 data model */ -struct i1905_dm { +struct i1905_topology { + bool enable; + uint8_t status; + //TODO: changelog table + uint32_t num_devices; + struct list_head devlist; /* list of i1905_device */ +}; + +/* represents own 1905 device */ +struct i1905_selfdevice { + uint32_t tsp; bool enabled; + uint8_t aladdr[6]; /* AL macaddress */ enum i1905_version version; - uint8_t macaddr[6]; /* AL macaddress */ - struct list_head reglist; /* list of struct i1905_registrar */ - struct list_head iflist; /* list of struct i1905_interface */ - struct list_head devlist; /* list of struct i1905_device */ + uint8_t regband; /* bitmap of i1905_registrar_type */ + + uint32_t num_interface; + struct list_head iflist; /* list of i1905_interface */ + struct i1905_fwdtable fwd; + struct i1905_topology topology; + + struct i1905_security security; + struct list_head reglist; /* list of i1905_registrar in network */ +}; + + +/* 1905 data model */ +struct i1905_dm { + struct i1905_selfdevice self; }; diff --git a/src/i1905_ubus.c b/src/i1905_ubus.c index 1bf8bdff59eb84c17afa69e86a13d56dbcd85ca3..9916cfb1b71615158dab10c0c4e27e55448ace24 100644 --- a/src/i1905_ubus.c +++ b/src/i1905_ubus.c @@ -6,6 +6,8 @@ #include <sys/socket.h> #include <sys/ioctl.h> #include <net/if_arp.h> +#include <net/if.h> +#include <arpa/inet.h> #include <json-c/json.h> #include <libubox/blobmsg.h> @@ -338,7 +340,7 @@ int i1905_publish_interface_objects(struct i1905_private *p) int ret = 0; - list_for_each_entry(iface, &p->iflist, list) { + list_for_each_entry(iface, &p->dm.self.iflist, list) { priv = (struct i1905_interface_private *)iface->priv; snprintf(objname, 63, "i1905.al.%s", iface->ifname);