Handle node id TLVs

This commit is contained in:
Matthias Schiffer 2012-10-04 21:41:28 +02:00
parent 8b4102d61a
commit b760b28c21

View file

@ -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");
}
}