From 26f5dc2ab09ed83380a374300b10a245f4c848f4 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 8 Oct 2012 02:45:07 +0200 Subject: Answer requests for single announcements --- ffd/send.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 69 insertions(+), 20 deletions(-) (limited to 'ffd/send.c') diff --git a/ffd/send.c b/ffd/send.c index 97ff3f1..283b36e 100644 --- a/ffd/send.c +++ b/ffd/send.c @@ -40,7 +40,7 @@ #include -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); } -- cgit v1.2.3