Skip to content
Snippets Groups Projects
Commit c97d395d authored by Anjan Chanda's avatar Anjan Chanda
Browse files

refine data-model and rx-cmdu processing

parent 8cb4ab71
Branches
Tags
No related merge requests found
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
#define TLV_TYPE_LAST (30) #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_3U_FAST_ETHERNET (0x0000)
#define MEDIA_TYPE_IEEE_802_3AB_GIGABIT_ETHERNET (0x0001) #define MEDIA_TYPE_IEEE_802_3AB_GIGABIT_ETHERNET (0x0001)
#define MEDIA_TYPE_IEEE_802_11B_2_4_GHZ (0x0100) #define MEDIA_TYPE_IEEE_802_11B_2_4_GHZ (0x0100)
...@@ -63,359 +63,249 @@ ...@@ -63,359 +63,249 @@
#define MEDIA_TYPE_UNKNOWN (0xFFFF) #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_2_4_GHZ (0x00)
#define IEEE80211_FREQUENCY_BAND_5_GHZ (0x01) #define IEEE80211_FREQUENCY_BAND_5_GHZ (0x01)
#define IEEE80211_FREQUENCY_BAND_60_GHZ (0x02) #define IEEE80211_FREQUENCY_BAND_60_GHZ (0x02)
// Media type structures detailed in "Tables 6-12 and 6-13" /* IEEE80211 roles */
struct _ieee80211SpecificInformation { #define IEEE80211_ROLE_REGISTRAR (0x00)
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
uint8_t ap_channel_band; // Hex value of dot11CurrentChannelBandwidth #define IEEE80211_ROLE_AP (0x0)
// (see "IEEE P802.11ac/D3.0" for description) #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; typedef uint8_t macaddr_t[6];
// Hex value of
// dot11CurrentChannelCenterFrequencyIndex2
// (see "IEEE P802.11ac/D3.0" for description)
};
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" */ /* TLV: Vendor specific info */
struct _genericPhyCommonData { struct tlv_vendor_specific {
uint8_t oui[3]; uint8_t oui[3];
uint8_t variant_index; uint16_t num_bytes;
uint8_t media_specific_bytes_nr; uint8_t bytes[];
uint8_t *media_specific_bytes; } __attribute__((packed));
};
/* 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;
};
/* 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 { /* IEEE 802.11 media specific info */
uint8_t al_mac_address[6]; struct ieee80211_info {
uint8_t local_interfaces_nr; uint8_t bssid[6];
struct _localInterfaceEntries *local_interfaces; 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") */ /* TLV: device information */
struct _bridgingTupleMacEntries { struct tlv_device_info {
uint8_t mac_address[6]; // MAC address of a 1905 device's network uint8_t aladdr[6];
// interface that belongs to a bridging tuple 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 { struct device_bridge_tuple_macaddr {
uint8_t bridging_tuples_nr; uint8_t macaddr[6];
struct _bridgingTupleEntries *bridging_tuples; } __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") */ /* TLV: Device bridging capability */
struct _non1905neighborEntries { struct tlv_device_bridge_caps {
uint8_t mac_address[6]; uint8_t num_tuples;
}; struct device_bridge_tuple tuple[];
} __attribute__((packed));
struct non1905NeighborDeviceListTLV {
uint8_t local_mac_address[6];
uint8_t non_1905_neighbors_nr;
struct _non1905neighborEntries *non_1905_neighbors;
};
/* 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 { struct non1905_neighbor {
uint8_t local_mac_address[6]; uint8_t macaddr[6];
uint8_t neighbors_nr;
struct _neighborEntries *neighbors;
}; };
/* 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 struct i1905_neighbor {
// neighbor AL, which connects to uint8_t aladdr[6];
// an interface in the receiving uint8_t has_bridge;
// AL } __attribute__((packed));
uint16_t intf_type; // Underlaying network technology /* TLV: 1905 neighbor devices */
// One of the MEDIA_TYPE_* values. 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 #define LINKMETRIC_QUERY_NEIGHBOR_ALL (0x00)
// on the same measurement period used to #define LINKMETRIC_QUERY_NEIGHBOR_SPECIFIC (0x01)
// estimate 'packet_errors'
uint16_t mac_throughput_capacity; // The maximum MAC throughput of the link #define LINKMETRIC_QUERY_TYPE_TX (0x00)
// estimated at the transmitter and #define LINKMETRIC_QUERY_TYPE_RX (0x01)
// expressed in Mb/s #define LINKMETRIC_QUERY_TYPE_BOTH (0x02)
uint16_t link_availability; // The estimated average percentage of /* TLV: link metric query */
// time that the link is available for struct tlv_linkmetric_query {
// data transmissions uint8_t nbr_type;
uint8_t nbr_macaddr[6];
uint16_t phy_rate; // This value is the PHY rate estimated at uint8_t query_type;
// the transmitter of the link expressed
// in Mb/s
}; };
struct transmitterLinkMetricTLV { struct tx_link_info {
uint8_t tlv_type; // Must always be set to uint8_t local_macaddr[6];
// TLV_TYPE_TRANSMITTER_LINK_METRIC 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 /* TLV: transmitter link metric */
// transmits the response message that struct tlv_tx_linkmetric {
// contains this TLV 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
};
//////////////////////////////////////////////////////////////////////////////// struct rx_link_info {
// Receiver link metric TLV associated structures ("Section 6.4.12") uint8_t local_macaddr[6];
//////////////////////////////////////////////////////////////////////////////// uint8_t neighbor_macaddr[6];
struct _receiverLinkMetricEntries { uint16_t mediatype;
uint8_t local_interface_address[6]; // MAC address of an interface in uint32_t errors;
// the receiving AL, which connects uint32_t packets;
// to an interface in the neighbor int8_t rssi; /* in dBm */
// AL } __attribute__((packed));
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
};
/* TLV: receiver link metric */
struct receiverLinkMetricTLV { struct receiverLinkMetricTLV {
uint8_t tlv_type; // Must always be set to uint8_t aladdr[6];
// TLV_TYPE_RECEIVER_LINK_METRIC 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 #define LINKMETRIC_RESULT_INVALID_NEIGHBOR (0x00)
// link metric is reported in this TLV
uint8_t receiver_link_metrics_nr; /* TLV: link metric result code */
struct _receiverLinkMetricEntries *receiver_link_metrics; struct tlv_linkmetric_result {
// Link metric information for the above uint8_t code;
// interface pair between the receiving AL } __attribute__((packed));
// and the neighbor AL
};
//////////////////////////////////////////////////////////////////////////////// /* TLV: searched role */
// Link metric result code TLV associated structures ("Section 6.4.13") struct tlv_searched_role {
//////////////////////////////////////////////////////////////////////////////// uint8_t role; /* one of IEEE80211_ROLE_* */
struct linkMetricResultCodeTLV { } __attribute__((packed));
uint8_t tlv_type; // Must always be set to
// TLV_TYPE_LINK_METRIC_RESULT_CODE
#define LINK_METRIC_RESULT_CODE_TLV_INVALID_NEIGHBOR (0x00) /* TLV: autoconfig frequency band */
uint8_t result_code; // One of the values from above struct tlv_autoconfig_band {
}; uint8_t band; /* one of IEEE80211_FREQUENCY_BAND_* */
} __attribute__((packed));
// Searched role TLV ("Section 6.4.14") /* TLV: supported role */
struct searchedRoleTLV { struct tlv_supported_role {
uint8_t role; // One of IEEE80211_ROLE_* uint8_t role; /* one of IEEE80211_ROLE_* */
}; } __attribute__((packed));
// Autoconfig frequency band TLV ("Section 6.4.15") /* TLV: supported frequency band */
struct autoconfigFreqBandTLV { struct tlv_supported_band {
uint8_t freq_band; // one of IEEE80211_FREQUENCY_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") /* TLV: wsc */
struct supportedFreqBandTLV { struct tlv_wsc {
uint8_t freq_band; // one of IEEE80211_FREQUENCY_BAND_* uint16_t framelen;
}; uint8_t frame[];
} __attribute__((packed));
// Supported frequency band TLV ("Section 6.4.18") struct media_info {
struct wscTLV { uint16_t type;
uint16_t wsc_frame_size; uint8_t sizeof_info;
uint8_t *wsc_frame; uint8_t info[]; /* ieee80211_info, ieee1901_info etc. */
}; } __attribute__((packed));
// Push button event notification TLV ("Section 6.4.19") /* TLV: push button event notification */
struct _mediaTypeEntries { struct tlv_pbc_notification {
uint16_t media_type; // One of the MEDIA_TYPE_* values uint8_t num_media;
struct media_info media[];
uint8_t media_specific_data_size; } __attribute__((packed));
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 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 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 { struct _genericPhyDeviceEntries {
uint8_t local_interface_address[6]; uint8_t local_interface_address[6];
// MAC address of the local interface // MAC address of the local interface
......
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
// TODO: combine 3 following headers into one // TODO: combine 3 following headers into one
#include "1905_defs.h" #include "1905_defs.h"
#include "i1905_tlvs.h" #include "1905_tlvs.h"
#include "lldp_tlvs.h" #include "lldp_tlvs.h"
...@@ -72,16 +72,18 @@ int i1905_handle_topology_discovery(struct i1905_interface_private *pif, ...@@ -72,16 +72,18 @@ int i1905_handle_topology_discovery(struct i1905_interface_private *pif,
if (hwaddr_is_zero(macaddr_origin)) { 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__); __func__);
return -1; return -1;
} }
ret = i1905_dm_neighour_update(i1905_interface_priv(pif), ret = i1905_dm_neighbor_discovered(i1905_interface_priv(pif),
aladdr_origin, macaddr_origin); aladdr_origin, macaddr_origin);
if (ret) { 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)); __func__, MAC2STR(macaddr_origin));
return -1; return -1;
...@@ -108,16 +110,18 @@ int i1905_handle_topology_notification(struct i1905_interface_private *pif, ...@@ -108,16 +110,18 @@ int i1905_handle_topology_notification(struct i1905_interface_private *pif,
if (hwaddr_is_zero(aladdr_origin)) { 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__); __func__);
return -1; return -1;
} }
ret = i1905_dm_neighour_update(i1905_interface_priv(pif), ret = i1905_dm_neighbor_changed(i1905_interface_priv(pif),
aladdr_origin, NULL); aladdr_origin);
if (ret) { 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)); __func__, MAC2STR(aladdr_origin));
return -1; return -1;
...@@ -146,31 +150,61 @@ int i1905_handle_topology_response(struct i1905_interface_private *pif, ...@@ -146,31 +150,61 @@ int i1905_handle_topology_response(struct i1905_interface_private *pif,
}; };
struct tlv *tv[6][16]; struct tlv *tv[6][16];
uint8_t aladdr_origin[6] = {0}; uint8_t aladdr_origin[6] = {0};
uint8_t macaddr_origin[6] = {0};
int ret; int ret;
cmdu_parse_tlvs(rxf, tv, a_policy, 6); cmdu_parse_tlvs(rxf, tv, a_policy, 6);
#if 0 if (tv[0][0]) {
if (hwaddr_is_zero(macaddr_origin)) { struct tlv_device_info *devinfo =
fprintf(stderr, "%s: Discard topo discovery from src = 0!\n", (struct tlv_device_info *)tv[0][0]->data;
__func__);
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), if (tv[1][0]) {
aladdr_origin, macaddr_origin); int num = 0;
if (ret) {
fprintf(stderr, "%s: Error updating DM for neighbor " MACFMT"\n",
__func__, MAC2STR(macaddr_origin));
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; return 0;
} }
...@@ -317,7 +351,7 @@ int i1905_process_cmdu(struct i1905_interface_private *pif, struct cmdu_buff *rx ...@@ -317,7 +351,7 @@ int i1905_process_cmdu(struct i1905_interface_private *pif, struct cmdu_buff *rx
// TODO: discard duplicates // TODO: discard duplicates
type = buf_get_be16(rxf->cdata->hdr.type); type = buf_get_be16((uint8_t *)&rxf->cdata->hdr.type);
if (i1905ftable[type]) { if (i1905ftable[type]) {
ret = i1905ftable[type](pif, rxf); ret = i1905ftable[type](pif, rxf);
......
...@@ -567,21 +567,27 @@ static int i1905_init_interfaces(struct i1905_private *p) ...@@ -567,21 +567,27 @@ static int i1905_init_interfaces(struct i1905_private *p)
sizeof(struct i1905_interface_private)); sizeof(struct i1905_interface_private));
if (iface) { if (iface) {
i1905_init_interface(iface, i1905_setup_interface_priv); i1905_init_interface(iface, i1905_setup_interface_priv);
iface->device = &p->dm.self;
memcpy(iface->aladdr, cfg->macaddr, 6); memcpy(iface->aladdr, cfg->macaddr, 6);
fprintf(stderr, "%s: aladdr = " MACFMT "\n", fprintf(stderr, "%s: aladdr = " MACFMT "\n",
__func__, MAC2STR(cfg->macaddr)); __func__, MAC2STR(cfg->macaddr));
list_add_tail(&iface->list, &p->iflist); list_add_tail(&iface->list, &p->dm.self.iflist);
} }
} }
return 0; return 0;
} }
static int i1905_init_al(struct i1905_private *p)
static int i1905_init_al()
{ {
return 0; int ret;
i1905_dm_init(&p->dm);
ret = i1905_init_interfaces(p);
return ret;
} }
void heartbeat_timer_cb(atimer_t *t) void heartbeat_timer_cb(atimer_t *t)
...@@ -595,7 +601,8 @@ int i1905_run_bridge_discovery(struct i1905_private *p) ...@@ -595,7 +601,8 @@ int i1905_run_bridge_discovery(struct i1905_private *p)
{ {
struct i1905_interface *iface; 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 cmdu_buff *frm = NULL;
uint8_t *lldpbuf; uint8_t *lldpbuf;
int ret = 0; int ret = 0;
...@@ -685,7 +692,8 @@ int i1905_run_topology_discovery(struct i1905_private *p) ...@@ -685,7 +692,8 @@ int i1905_run_topology_discovery(struct i1905_private *p)
{ {
struct i1905_interface *iface; 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 cmdu_buff *frm = NULL;
struct tlv *t; struct tlv *t;
int ret = 0; int ret = 0;
...@@ -781,7 +789,6 @@ int i1905_init(void **priv, void *cfg) ...@@ -781,7 +789,6 @@ int i1905_init(void **priv, void *cfg)
return -1; return -1;
INIT_LIST_HEAD(&p->iflist);
INIT_LIST_HEAD(&p->extlist); INIT_LIST_HEAD(&p->extlist);
p->ctx = ubus_connect(NULL); p->ctx = ubus_connect(NULL);
...@@ -800,7 +807,7 @@ int i1905_init(void **priv, void *cfg) ...@@ -800,7 +807,7 @@ int i1905_init(void **priv, void *cfg)
__func__, p, p->cfg.registrar_2g, p->cfg.registrar_5g); __func__, p, p->cfg.registrar_2g, p->cfg.registrar_5g);
ret = i1905_init_interfaces(p); ret = i1905_init_al(p);
if (ret) if (ret)
goto out_err; goto out_err;
......
...@@ -14,6 +14,7 @@ struct i1905_private { ...@@ -14,6 +14,7 @@ struct i1905_private {
atimer_t topotimer; atimer_t topotimer;
struct list_head extlist; struct list_head extlist;
struct list_head iflist; struct list_head iflist;
struct i1905_dm dm;
struct ubus_context *ctx; struct ubus_context *ctx;
struct ubus_object obj; struct ubus_object obj;
...@@ -29,7 +30,7 @@ struct i1905_interface_private { ...@@ -29,7 +30,7 @@ struct i1905_interface_private {
struct cmdu_queue rxqueue; struct cmdu_queue rxqueue;
struct worker rxwork; struct worker rxwork;
void *iface; void *iface; /* points to i1905_interface */
struct ubus_object obj; struct ubus_object obj;
struct ubus_object_type obj_type; struct ubus_object_type obj_type;
}; };
...@@ -71,7 +72,14 @@ extern struct i1905_dm *i1905_dm_get(); ...@@ -71,7 +72,14 @@ extern struct i1905_dm *i1905_dm_get();
extern int i1905_dm_init(struct i1905_dm *dm); extern int i1905_dm_init(struct i1905_dm *dm);
extern int i1905_dm_free(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, 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 */ #endif /* I1905_H */
...@@ -23,36 +23,220 @@ ...@@ -23,36 +23,220 @@
#include <libubox/utils.h> #include <libubox/utils.h>
#include <libubus.h> #include <libubus.h>
#include <easy/easy.h>
#include "cmdu.h" #include "cmdu.h"
#include "i1905_dm.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, struct i1905_interface *i1905_dm_neighbor_interface_create(void)
uint8_t *macaddr)
{ {
struct i1905_interface *rif;
//TODO: lookup aladdr/macaddr in DM rif = calloc(1, sizeof(*rif));
// if not available, add to DM if (!rif) {
// if available, update tsp fprintf(stderr, "-ENOMEM\n");
// return NULL;
// if tsp_lastupdated = 0 or > 10 secs, send topo query }
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; return 0;
} }
int i1905_dm_init(struct i1905_dm *dm) 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); self->security.method = I1905_SECURITY_PBC;
INIT_LIST_HEAD(&dm->iflist);
INIT_LIST_HEAD(&dm->devlist);
INIT_LIST_HEAD(&dm->fwd.rulelist); INIT_LIST_HEAD(&self->reglist);
return 0; return 0;
} }
......
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <netinet/in.h>
#include <arpa/inet.h>
enum i1905_version { enum i1905_version {
I1905_VERSION_DOT_1, I1905_VERSION_DOT_1,
...@@ -14,15 +17,17 @@ enum i1905_version { ...@@ -14,15 +17,17 @@ enum i1905_version {
}; };
enum i1905_registrar_type { enum i1905_registrar_type {
I1905_REGISTRAR_2G, I1905_REGISTRAR_NONE,
I1905_REGISTRAR_5G, I1905_REGISTRAR_2G = 1 << 0,
I1905_REGISTRAR_60G, I1905_REGISTRAR_5G = 1 << 1,
I1905_REGISTRAR_60G = 1 << 2,
_I1905_REGISTRAR_MAX, //_I1905_REGISTRAR_MAX,
I1905_NUM_REGISTRAR = _I1905_REGISTRAR_MAX, //I1905_NUM_REGISTRAR = _I1905_REGISTRAR_MAX,
}; };
enum i1905_security_method { enum i1905_security_method {
I1905_SECURITY_UNKNOWN,
I1905_SECURITY_UCPK, I1905_SECURITY_UCPK,
I1905_SECURITY_PBC, I1905_SECURITY_PBC,
I1905_SECURITY_NFC, I1905_SECURITY_NFC,
...@@ -52,7 +57,7 @@ struct i1905_rinterface { ...@@ -52,7 +57,7 @@ struct i1905_rinterface {
struct list_head list; struct list_head list;
}; };
struct i1905_neighbor { struct i1905_net_neighbor {
uint8_t macaddr[6]; uint8_t macaddr[6];
uint8_t num_ifaces; uint8_t num_ifaces;
struct list_head riflist; /* list of struct i1905_rinterface */ struct list_head riflist; /* list of struct i1905_rinterface */
...@@ -143,29 +148,75 @@ struct i1905_interface { ...@@ -143,29 +148,75 @@ struct i1905_interface {
uint8_t macaddr[6]; uint8_t macaddr[6];
uint8_t aladdr[6]; /* FIXME: or have i1905_device ptr? */ uint8_t aladdr[6]; /* FIXME: or have i1905_device ptr? */
uint32_t ifstatus; uint32_t ifstatus;
void *device; /* points to device it belongs */
enum i1905_mediatype media; /* media type */ enum i1905_mediatype media; /* media type */
uint8_t *mediainfo; /* ieee80211_info, ieee1901_info etc. */
struct i1905_genphy genphy; struct i1905_genphy genphy;
bool allow_ifpower; /* allow set power state ? */ bool allow_ifpower; /* allow set power state ? */
enum i1905_ifpowerstate power; enum i1905_ifpowerstate power;
uint32_t num_vendor;
struct list_head vendorlist; /* list of vendor properties */ struct list_head vendorlist; /* list of vendor properties */
uint32_t num_links;
struct list_head iflinklist; /* list of interface 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; struct list_head list;
void *priv; /* interface private data */ void *priv; /* interface private data */
}; };
struct i1905_security { struct i1905_security {
//enum i1905_sectype method; //TODO enum i1905_security_method method;
uint8_t password[64]; 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]; 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; 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 name[128]; /* friendly name */
char manufacturer[128]; char manufacturer[128];
char model[128]; char model[128];
...@@ -180,21 +231,52 @@ struct i1905_device { ...@@ -180,21 +231,52 @@ struct i1905_device {
uint32_t num_neighbor_l2; uint32_t num_neighbor_l2;
uint32_t num_brtuple; 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_topology {
struct i1905_dm { 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; bool enabled;
uint8_t aladdr[6]; /* AL macaddress */
enum i1905_version version; enum i1905_version version;
uint8_t macaddr[6]; /* AL macaddress */ uint8_t regband; /* bitmap of i1905_registrar_type */
struct list_head reglist; /* list of struct i1905_registrar */
struct list_head iflist; /* list of struct i1905_interface */ uint32_t num_interface;
struct list_head devlist; /* list of struct i1905_device */ struct list_head iflist; /* list of i1905_interface */
struct i1905_fwdtable fwd; 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;
}; };
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <net/if_arp.h> #include <net/if_arp.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <json-c/json.h> #include <json-c/json.h>
#include <libubox/blobmsg.h> #include <libubox/blobmsg.h>
...@@ -338,7 +340,7 @@ int i1905_publish_interface_objects(struct i1905_private *p) ...@@ -338,7 +340,7 @@ int i1905_publish_interface_objects(struct i1905_private *p)
int ret = 0; 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; priv = (struct i1905_interface_private *)iface->priv;
snprintf(objname, 63, "i1905.al.%s", iface->ifname); snprintf(objname, 63, "i1905.al.%s", iface->ifname);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment