Handle node id TLVs
This commit is contained in:
parent
8b4102d61a
commit
b760b28c21
1 changed files with 58 additions and 25 deletions
83
ffd/ffd.c
83
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");
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue