diff options
-rw-r--r-- | ffd/ffd.c | 19 | ||||
-rw-r--r-- | ffd/ffd.h | 1 | ||||
-rw-r--r-- | ffd/send.c | 16 | ||||
-rw-r--r-- | ffd/tlv_types.h | 10 |
4 files changed, 46 insertions, 0 deletions
@@ -191,6 +191,17 @@ 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_ack_req(const ffd_tlv_ack_req_t *tlv_req, size_t len, handle_tlv_arg_t *arg) { + if (len < sizeof(ffd_tlv_ack_req_t)) { + fprintf(stderr, "warn: received short acknowledement request TLV.\n"); + return; + } + + ffd_neigh_t *neigh = get_tlv_neigh(arg); + + ffd_send_ack(arg->iface, 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) { if (len < sizeof(ffd_tlv_hello_t)) { fprintf(stderr, "warn: received short hello TLV.\n"); @@ -392,6 +403,14 @@ static void handle_tlv_announce_req(const ffd_tlv_announce_req_t *tlv_req, size_ static void handle_tlv(ffd_tlv_type_t type, const void *data, size_t len, void *arg) { switch (type) { + case TLV_ACK_REQ: + handle_tlv_ack_req(data, len, arg); + return; + + case TLV_ACK: + /* we don't send ack reqs */ + return; + case TLV_HELLO: handle_tlv_hello(data, len, arg); return; @@ -152,6 +152,7 @@ ffd_metric_seqno_t ffd_announce_get_metric(const ffd_announce_t *announce); void ffd_announce_update_nexthop(ffd_announce_t *announce); ffd_announce_t* ffd_announce_new(void); +void ffd_send_ack(ffd_iface_t *iface, 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_announce_request(ffd_iface_t *iface, ffd_neigh_t *neigh, ffd_node_id_t node, uint16_t type, uint16_t key, bool with_data); @@ -72,6 +72,22 @@ 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) { + ffd_packet_t *packet = alloca(sizeof(ffd_packet_t)+FFD_PACKET_MAX); + + packet->version_magic = htons(FFD_VERSION_MAGIC); + packet->len = 0; + + ffd_tlv_ack_t *ack = ffd_tlv_add(packet, FFD_PACKET_MAX, TLV_ACK, sizeof(ffd_tlv_ack_t)); + if (!ack) + return; + + 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"); +} + static void add_ihus(ffd_packet_t *packet, size_t max_len, const ffd_iface_t *iface) { const ffd_neigh_t *neigh; diff --git a/ffd/tlv_types.h b/ffd/tlv_types.h index afe793a..07eba53 100644 --- a/ffd/tlv_types.h +++ b/ffd/tlv_types.h @@ -30,6 +30,16 @@ #include "tlv.h" +typedef struct __attribute__((packed)) _ffd_tlv_ack_req_t { + uint16_t reserved; + uint16_t nonce; + uint16_t interval; +} ffd_tlv_ack_req_t; + +typedef struct __attribute__((packed)) _ffd_tlv_ack_t { + uint16_t nonce; +} ffd_tlv_ack_t; + typedef struct __attribute__((packed)) _ffd_tlv_hello_t { uint16_t reserved; uint16_t seqno; |