summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2012-10-04 21:41:28 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2012-10-04 21:41:28 +0200
commitb760b28c21515265f8d09c46011290a9a22b871e (patch)
treeb355a0ad55293c01a7ddbfb4009336687a1d4ff6
parent8b4102d61aa36d96437199f67bd4a6e9a335d2fa (diff)
downloadffd-b760b28c21515265f8d09c46011290a9a22b871e.tar
ffd-b760b28c21515265f8d09c46011290a9a22b871e.zip
Handle node id TLVs
-rw-r--r--ffd/ffd.c83
1 files changed, 58 insertions, 25 deletions
diff --git a/ffd/ffd.c b/ffd/ffd.c
index b1117f0..3512906 100644
--- a/ffd/ffd.c
+++ b/ffd/ffd.c
@@ -100,11 +100,7 @@ static bool init_self(void) {
announce->key = 1337;
announce->interval = 6000;
- ffd_nexthop_t *nexthop = announce->nexthop_list = malloc(sizeof(ffd_nexthop_t));
-
- nexthop->addr = ETH_ADDR_UNSPEC;
- nexthop->metric_seqno.metric = 0;
- nexthop->metric_seqno.seqno = 0;
+ announce->nexthop_list = calloc(1, sizeof(ffd_nexthop_t));
return true;
}
@@ -185,7 +181,18 @@ static void update_netifs(void) {
}
}
-static void handle_tlv_hello(const ffd_tlv_hello_t *tlv_hello, size_t len, const eth_addr_t *addr, ffd_iface_t *iface) {
+typedef struct _handle_tlv_arg_t {
+ ffd_iface_t *iface;
+ const eth_addr_t *addr;
+
+ ffd_node_id_t node_id;
+} handle_tlv_arg_t;
+
+static inline ffd_neigh_t* get_tlv_neigh(handle_tlv_arg_t *arg) {
+ return ffd_neigh_get(arg->iface, arg->addr);
+}
+
+static void handle_tlv_hello(const ffd_tlv_hello_t *tlv_hello, size_t len, handle_tlv_arg_t *arg) {
if (len < sizeof(ffd_tlv_hello_t)) {
fprintf(stderr, "warn: received short hello TLV.\n");
return;
@@ -193,7 +200,7 @@ static void handle_tlv_hello(const ffd_tlv_hello_t *tlv_hello, size_t len, const
fprintf(stderr, "debug: received hello with seqno %u.\n", ntohs(tlv_hello->seqno));
- ffd_neigh_t *neigh = ffd_neigh_get(iface, addr);
+ ffd_neigh_t *neigh = get_tlv_neigh(arg);
uint16_t seqno = ntohs(tlv_hello->seqno);
@@ -226,12 +233,12 @@ static void handle_tlv_hello(const ffd_tlv_hello_t *tlv_hello, size_t len, const
neigh->last_hello = now;
if (neigh->hello_log == 1) /* new or reset neighbour */
- ffd_neigh_reset(iface, neigh);
+ ffd_neigh_reset(arg->iface, neigh);
fprintf(stderr, "debug: accepted hello, log %04x, rxcost is %u, cost is %u now.\n", neigh->hello_log, ffd_neigh_get_rxcost(neigh), ffd_neigh_get_cost(neigh));
}
-static void handle_tlv_ihu(const ffd_tlv_ihu_t *tlv_ihu, size_t len, const eth_addr_t *addr, ffd_iface_t *iface) {
+static void handle_tlv_ihu(const ffd_tlv_ihu_t *tlv_ihu, size_t len, handle_tlv_arg_t *arg) {
if (len < sizeof(ffd_tlv_ihu_t)) {
fprintf(stderr, "warn: received short IHU TLV.\n");
return;
@@ -243,21 +250,39 @@ static void handle_tlv_ihu(const ffd_tlv_ihu_t *tlv_ihu, size_t len, const eth_a
return;
}
- if (memcmp(tlv_ihu->address, &iface->addr, sizeof(eth_addr_t)) != 0)
+ if (memcmp(tlv_ihu->address, &arg->iface->addr, sizeof(eth_addr_t)) != 0)
return;
}
else if (tlv_ihu->ae != ADDR_ENC_UNSPEC) {
return;
}
- ffd_neigh_t *neigh = ffd_neigh_get(iface, addr);
+ ffd_neigh_t *neigh = get_tlv_neigh(arg);
neigh->last_ihu = now;
neigh->txcost = ntohs(tlv_ihu->rxcost);
fprintf(stderr, "debug: accepted IHU, txcost is %u, cost is %u now.\n", neigh->txcost, ffd_neigh_get_cost(neigh));
}
-static void handle_tlv_announce_req(const ffd_tlv_announce_req_t *tlv_req, size_t len, const eth_addr_t *addr, ffd_iface_t *iface) {
+static void handle_tlv_node_id(const ffd_tlv_node_id_t *tlv_node_id, size_t len, handle_tlv_arg_t *arg) {
+ if (len < sizeof(ffd_tlv_node_id_t)) {
+ fprintf(stderr, "warn: received short node id TLV.\n");
+ return;
+ }
+
+ arg->node_id = tlv_node_id->id;
+}
+
+static void handle_tlv_update(const ffd_tlv_node_id_t *tlv_node_id, size_t len, handle_tlv_arg_t *arg) {
+ if (len < sizeof(ffd_tlv_update_t)) {
+ fprintf(stderr, "warn: received short update TLV.\n");
+ return;
+ }
+
+ fprintf(stderr, "debug: update received from %04x%04x.\n", ntohl(*(uint32_t*)arg->node_id.id), ntohl(*(uint32_t*)(arg->node_id.id+4)));
+}
+
+static void handle_tlv_announce_req(const ffd_tlv_announce_req_t *tlv_req, size_t len, handle_tlv_arg_t *arg) {
if (len < sizeof(ffd_tlv_announce_req_t)) {
fprintf(stderr, "warn: received short announce request TLV.\n");
return;
@@ -269,32 +294,33 @@ static void handle_tlv_announce_req(const ffd_tlv_announce_req_t *tlv_req, size_
announce = NULL;
}
- ffd_send_update(iface, ffd_neigh_get(iface, addr), announce);
+ ffd_send_update(arg->iface, get_tlv_neigh(arg), announce);
}
static void handle_tlv(ffd_tlv_type_t type, const void *data, size_t len, void *arg) {
- const struct sockaddr_ll *from = arg;
- const eth_addr_t *addr = (const eth_addr_t*)from->sll_addr;
- ffd_iface_t *iface = get_iface(from->sll_ifindex);
-
- if (!iface)
- return;
-
switch (type) {
case TLV_HELLO:
- handle_tlv_hello(data, len, addr, iface);
+ handle_tlv_hello(data, len, arg);
return;
case TLV_IHU:
- handle_tlv_ihu(data, len, addr, iface);
+ handle_tlv_ihu(data, len, arg);
+ return;
+
+ case TLV_NODE_ID:
+ handle_tlv_node_id(data, len, arg);
+ return;
+
+ case TLV_UPDATE:
+ handle_tlv_update(data, len, arg);
return;
case TLV_ANNOUNCE_REQ:
- handle_tlv_announce_req(data, len, addr, iface);
+ handle_tlv_announce_req(data, len, arg);
return;
default:
- fprintf(stderr, "debug: received unknown TLV %u on %s.\n", type, iface->name);
+ fprintf(stderr, "debug: received unknown TLV %u on %s.\n", type, ((handle_tlv_arg_t*)arg)->iface->name);
return;
}
}
@@ -321,7 +347,14 @@ static void receive_packet(void) {
return;
}
- if (!ffd_tlv_parse(packet, handle_tlv, &from)) {
+ handle_tlv_arg_t arg = { .iface = get_iface(from.sll_ifindex), .addr = (const eth_addr_t*)&from.sll_addr };
+
+ if (!arg.iface) {
+ fprintf(stderr, "debug: received packet on unknown interface.\n");
+ return;
+ }
+
+ if (!ffd_tlv_parse(packet, handle_tlv, &arg)) {
fprintf(stderr, "debug: received invalid packet.\n");
}
}