summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2012-10-05 04:56:08 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2012-10-05 04:56:08 +0200
commit4cf3389fcf094c095d685a3e9f65a5d1fafff717 (patch)
tree28178dbd858ea08fda978c9aa63e8dd28bd16b6c
parentbb7392551ed8578171941b81cf3ed2cfc4ad2b1b (diff)
downloadffd-4cf3389fcf094c095d685a3e9f65a5d1fafff717.tar
ffd-4cf3389fcf094c095d685a3e9f65a5d1fafff717.zip
Add ack request handling
-rw-r--r--ffd/ffd.c19
-rw-r--r--ffd/ffd.h1
-rw-r--r--ffd/send.c16
-rw-r--r--ffd/tlv_types.h10
4 files changed, 46 insertions, 0 deletions
diff --git a/ffd/ffd.c b/ffd/ffd.c
index 5f17446..ccba14d 100644
--- a/ffd/ffd.c
+++ b/ffd/ffd.c
@@ -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;
diff --git a/ffd/ffd.h b/ffd/ffd.h
index e0f1954..a93c855 100644
--- a/ffd/ffd.h
+++ b/ffd/ffd.h
@@ -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);
diff --git a/ffd/send.c b/ffd/send.c
index 48c44fc..779476b 100644
--- a/ffd/send.c
+++ b/ffd/send.c
@@ -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;