Answer requests for single announcements
This commit is contained in:
parent
46a05f9664
commit
26f5dc2ab0
4 changed files with 109 additions and 46 deletions
|
@ -138,3 +138,28 @@ ffd_announce_t* ffd_announce_new(void) {
|
|||
|
||||
return a;
|
||||
}
|
||||
|
||||
ffd_announce_t* ffd_announce_find(const ffd_node_id_t *node, uint16_t type, uint16_t key) {
|
||||
ffd_announce_t *announce;
|
||||
for (announce = announce_list; announce; announce = announce->next) {
|
||||
if (ffd_are_node_ids_equal(&announce->node, node)
|
||||
&& announce->type == type
|
||||
&& announce->key == key)
|
||||
return announce;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ffd_announce_t* ffd_announce_get(const ffd_node_id_t *node, uint16_t type, uint16_t key) {
|
||||
ffd_announce_t *announce = ffd_announce_find(node, type, key);
|
||||
|
||||
if (!announce) {
|
||||
announce = ffd_announce_new();
|
||||
announce->node = *node;
|
||||
announce->type = type;
|
||||
announce->key = key;
|
||||
}
|
||||
|
||||
return announce;
|
||||
}
|
||||
|
|
36
ffd/ffd.c
36
ffd/ffd.c
|
@ -198,7 +198,7 @@ static void handle_tlv_ack_req(const ffd_tlv_ack_req_t *tlv_req, size_t len, han
|
|||
|
||||
ffd_neigh_t *neigh = get_tlv_neigh(arg);
|
||||
|
||||
ffd_send_ack(arg->iface, neigh, ntohs(tlv_req->nonce));
|
||||
ffd_send_ack(neigh, ntohs(tlv_req->nonce));
|
||||
}
|
||||
|
||||
static void handle_tlv_hello(const ffd_tlv_hello_t *tlv_hello, size_t len, handle_tlv_arg_t *arg) {
|
||||
|
@ -284,24 +284,6 @@ static void handle_tlv_node_id(const ffd_tlv_node_id_t *tlv_node_id, size_t len,
|
|||
arg->node_id = tlv_node_id->id;
|
||||
}
|
||||
|
||||
static ffd_announce_t* get_announce(const ffd_node_id_t *node, uint16_t type, uint16_t key) {
|
||||
ffd_announce_t *announce;
|
||||
for (announce = announce_list; announce; announce = announce->next) {
|
||||
if (ffd_are_node_ids_equal(&announce->node, node)
|
||||
&& announce->type == type
|
||||
&& announce->key == key)
|
||||
return announce;
|
||||
}
|
||||
|
||||
/* not found */
|
||||
announce = ffd_announce_new();
|
||||
announce->node = *node;
|
||||
announce->type = type;
|
||||
announce->key = key;
|
||||
|
||||
return announce;
|
||||
}
|
||||
|
||||
static ffd_nexthop_t* find_nexthop(const ffd_announce_t *announce, ffd_neigh_t *neigh) {
|
||||
ffd_nexthop_t *nexthop;
|
||||
for (nexthop = announce->nexthop_list; nexthop; nexthop = nexthop->next) {
|
||||
|
@ -342,7 +324,7 @@ static void handle_tlv_update(const ffd_tlv_update_t *tlv_update, size_t len, ha
|
|||
|
||||
fprintf(stderr, "debug: update received from %04x%04x.\n", ntohl(*(uint32_t*)arg->node_id.id), ntohl(*(uint32_t*)(arg->node_id.id+4)));
|
||||
|
||||
ffd_announce_t *announce = get_announce(&arg->node_id, ntohs(tlv_update->type), ntohs(tlv_update->key));
|
||||
ffd_announce_t *announce = ffd_announce_get(&arg->node_id, ntohs(tlv_update->type), ntohs(tlv_update->key));
|
||||
ffd_metric_seqno_t ms = { ntohs(tlv_update->metric), ntohs(tlv_update->seqno) };
|
||||
bool feasible = ffd_is_feasible(announce, ms);
|
||||
|
||||
|
@ -387,13 +369,17 @@ static void handle_tlv_announce_req(const ffd_tlv_announce_req_t *tlv_req, size_
|
|||
return;
|
||||
}
|
||||
|
||||
ffd_announce_t *announce = NULL;
|
||||
|
||||
if (!ffd_is_node_id_unspec(&tlv_req->node)) {
|
||||
announce = NULL;
|
||||
if (ffd_is_node_id_unspec(&tlv_req->node)) {
|
||||
ffd_send_update(NULL, get_tlv_neigh(arg), NULL, tlv_req->flags & FFD_UPDATE_WITH_DATA);
|
||||
}
|
||||
else {
|
||||
ffd_announce_t *announce = ffd_announce_find(&tlv_req->node, ntohs(tlv_req->type), ntohs(tlv_req->key));
|
||||
|
||||
ffd_send_update(arg->iface, get_tlv_neigh(arg), announce, tlv_req->flags & FFD_UPDATE_WITH_DATA);
|
||||
if (announce)
|
||||
ffd_send_update(NULL, get_tlv_neigh(arg), announce, tlv_req->flags & FFD_UPDATE_WITH_DATA);
|
||||
else
|
||||
ffd_send_retract(get_tlv_neigh(arg), tlv_req->node, ntohs(tlv_req->type), ntohs(tlv_req->key));
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_tlv(ffd_tlv_type_t type, const void *data, size_t len, void *arg) {
|
||||
|
|
|
@ -186,10 +186,13 @@ static inline bool ffd_is_feasible(const ffd_announce_t *announce, ffd_metric_se
|
|||
void ffd_announce_update(ffd_announce_t *announce);
|
||||
void ffd_announce_update_nexthop(ffd_announce_t *announce, ffd_nexthop_t *nexthop, ffd_metric_seqno_t ms, uint16_t interval);
|
||||
ffd_announce_t* ffd_announce_new(void);
|
||||
ffd_announce_t* ffd_announce_find(const ffd_node_id_t *node, uint16_t type, uint16_t key);
|
||||
ffd_announce_t* ffd_announce_get(const ffd_node_id_t *node, uint16_t type, uint16_t key);
|
||||
|
||||
void ffd_send_ack(ffd_iface_t *iface, ffd_neigh_t *neigh, uint16_t nonce);
|
||||
void ffd_send_ack(ffd_neigh_t *neigh, uint16_t nonce);
|
||||
void ffd_send_hellos(void);
|
||||
void ffd_send_update(ffd_iface_t *iface, ffd_neigh_t *neigh, ffd_announce_t *announce, bool with_data);
|
||||
void ffd_send_retract(ffd_neigh_t *neigh, ffd_node_id_t node, uint16_t type, uint16_t key);
|
||||
void ffd_send_announce_request(ffd_iface_t *iface, ffd_neigh_t *neigh, ffd_node_id_t node, uint16_t type, uint16_t key, bool with_data);
|
||||
|
||||
#endif /* _FFD_FFD_H_ */
|
||||
|
|
89
ffd/send.c
89
ffd/send.c
|
@ -40,7 +40,7 @@
|
|||
#include <sys/uio.h>
|
||||
|
||||
|
||||
static bool send_eth(const eth_addr_t *addr, unsigned ifindex, void *buf, size_t len) {
|
||||
static bool send_eth(const eth_addr_t *addr, unsigned ifindex, const void *buf, size_t len) {
|
||||
static const uint8_t zeros[46] = {0};
|
||||
|
||||
struct sockaddr_ll sa;
|
||||
|
@ -52,7 +52,7 @@ static bool send_eth(const eth_addr_t *addr, unsigned ifindex, void *buf, size_t
|
|||
memcpy(sa.sll_addr, addr->d, ETH_ALEN);
|
||||
|
||||
struct iovec vec[2] = {
|
||||
{ .iov_base = buf, .iov_len = len },
|
||||
{ .iov_base = (void*)buf, .iov_len = len },
|
||||
{ .iov_base = (void*)zeros, .iov_len = sizeof(zeros) - len },
|
||||
};
|
||||
|
||||
|
@ -72,7 +72,43 @@ static bool send_eth(const eth_addr_t *addr, unsigned ifindex, void *buf, size_t
|
|||
return true;
|
||||
}
|
||||
|
||||
void ffd_send_ack(ffd_iface_t *iface, ffd_neigh_t *neigh, uint16_t nonce) {
|
||||
static inline bool send_neigh(const ffd_neigh_t *neigh, const ffd_packet_t *packet) {
|
||||
if (!neigh->iface)
|
||||
return false;
|
||||
|
||||
if (!send_eth(&neigh->addr, neigh->iface->ifindex, packet, sizeof(ffd_packet_t)+ntohs(packet->len))) {
|
||||
fprintf(stderr, "send_eth: %m\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool send_iface(const ffd_iface_t *iface, const ffd_packet_t *packet) {
|
||||
if (!send_eth(&ffd_addr, iface->ifindex, packet, sizeof(ffd_packet_t)+ntohs(packet->len))) {
|
||||
fprintf(stderr, "send_eth: %m\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void send_broadcast(const ffd_packet_t *packet) {
|
||||
ffd_iface_t *iface;
|
||||
for (iface = iface_list; iface; iface = iface->next)
|
||||
send_iface(iface, packet);
|
||||
}
|
||||
|
||||
static inline void send_any(const ffd_iface_t *iface, const ffd_neigh_t *neigh, const ffd_packet_t *packet) {
|
||||
if (neigh)
|
||||
send_neigh(neigh, packet);
|
||||
else if(iface)
|
||||
send_iface(iface, packet);
|
||||
else
|
||||
send_broadcast(packet);
|
||||
}
|
||||
|
||||
void ffd_send_ack(ffd_neigh_t *neigh, uint16_t nonce) {
|
||||
ffd_packet_t *packet = alloca(sizeof(ffd_packet_t)+FFD_PACKET_MAX);
|
||||
|
||||
packet->version_magic = htons(FFD_VERSION_MAGIC);
|
||||
|
@ -84,8 +120,7 @@ void ffd_send_ack(ffd_iface_t *iface, ffd_neigh_t *neigh, uint16_t nonce) {
|
|||
|
||||
ack->nonce = htons(nonce);
|
||||
|
||||
if (!send_eth(&neigh->addr, iface->ifindex, packet, sizeof(ffd_packet_t)+ntohs(packet->len)))
|
||||
fprintf(stderr, "send_eth: %m\n");
|
||||
send_neigh(neigh, packet);
|
||||
}
|
||||
|
||||
static void add_ihus(ffd_packet_t *packet, size_t max_len, const ffd_iface_t *iface) {
|
||||
|
@ -127,8 +162,7 @@ void ffd_send_hellos(void) {
|
|||
|
||||
add_ihus(packet, FFD_PACKET_MAX, iface);
|
||||
|
||||
if (!send_eth(&ffd_addr, iface->ifindex, packet, sizeof(ffd_packet_t)+ntohs(packet->len)))
|
||||
fprintf(stderr, "send_eth: %m\n");
|
||||
send_iface(iface, packet);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,11 +226,6 @@ void ffd_send_update(ffd_iface_t *iface, ffd_neigh_t *neigh, ffd_announce_t *ann
|
|||
packet->version_magic = htons(FFD_VERSION_MAGIC);
|
||||
packet->len = 0;
|
||||
|
||||
const eth_addr_t *addr = &ffd_addr;
|
||||
|
||||
if (neigh)
|
||||
addr = &neigh->addr;
|
||||
|
||||
if (announce) {
|
||||
add_update(packet, FFD_PACKET_MAX, NULL, announce, with_data);
|
||||
}
|
||||
|
@ -206,8 +235,7 @@ void ffd_send_update(ffd_iface_t *iface, ffd_neigh_t *neigh, ffd_announce_t *ann
|
|||
ffd_announce_t *a;
|
||||
for (a = announce_list; a; a = a->next) {
|
||||
if (!add_update(packet, FFD_PACKET_MAX, &node_id, a, with_data)) {
|
||||
if (!send_eth(addr, iface->ifindex, packet, sizeof(ffd_packet_t)+ntohs(packet->len)))
|
||||
fprintf(stderr, "send_eth: %m\n");
|
||||
send_any(iface, neigh, packet);
|
||||
|
||||
node_id = FFD_NODE_ID_UNSPEC;
|
||||
packet->len = 0;
|
||||
|
@ -220,10 +248,32 @@ void ffd_send_update(ffd_iface_t *iface, ffd_neigh_t *neigh, ffd_announce_t *ann
|
|||
}
|
||||
}
|
||||
|
||||
if (packet->len) {
|
||||
if (!send_eth(addr, iface->ifindex, packet, sizeof(ffd_packet_t)+ntohs(packet->len)))
|
||||
fprintf(stderr, "send_eth: %m\n");
|
||||
}
|
||||
if (packet->len)
|
||||
send_any(iface, neigh, packet);
|
||||
}
|
||||
|
||||
void ffd_send_retract(ffd_neigh_t *neigh, ffd_node_id_t node, uint16_t type, uint16_t key) {
|
||||
ffd_packet_t *packet = alloca(sizeof(ffd_packet_t)+FFD_PACKET_MAX);
|
||||
|
||||
packet->version_magic = htons(FFD_VERSION_MAGIC);
|
||||
packet->len = 0;
|
||||
|
||||
if (!add_node_id(packet, FFD_PACKET_MAX, node))
|
||||
return;
|
||||
|
||||
ffd_tlv_update_t *req = ffd_tlv_add(packet, FFD_PACKET_MAX, TLV_UPDATE, sizeof(ffd_tlv_update_t));
|
||||
if (!req)
|
||||
return;
|
||||
|
||||
req->flags = 0;
|
||||
req->reserved = 0;
|
||||
req->interval = htons(FFD_UPDATE_INTERVAL);
|
||||
req->seqno = 0;
|
||||
req->metric = 0xffff; /* no need to htons */
|
||||
req->type = htons(type);
|
||||
req->key = htons(key);
|
||||
|
||||
send_neigh(neigh, packet);
|
||||
}
|
||||
|
||||
void ffd_send_announce_request(ffd_iface_t *iface, ffd_neigh_t *neigh, ffd_node_id_t node, uint16_t type, uint16_t key, bool with_data) {
|
||||
|
@ -245,6 +295,5 @@ void ffd_send_announce_request(ffd_iface_t *iface, ffd_neigh_t *neigh, ffd_node_
|
|||
if (with_data)
|
||||
req->flags |= FFD_UPDATE_WITH_DATA;
|
||||
|
||||
if (!send_eth(&ffd_addr, iface->ifindex, packet, sizeof(ffd_packet_t)+ntohs(packet->len)))
|
||||
fprintf(stderr, "send_eth: %m\n");
|
||||
send_any(iface, neigh, packet);
|
||||
}
|
||||
|
|
Reference in a new issue