From a6fa92d1c8774a704fd4a869fc5d7799528b084f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 26 Mar 2013 05:39:11 +0100 Subject: Send announce and seqno requests --- src/announce.c | 16 ++++++++-------- src/babel.c | 2 +- src/babel.h | 48 ++++++++++++++++++++++++++++++------------------ src/send.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/tlv_types.c | 14 +++++++------- 5 files changed, 93 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/announce.c b/src/announce.c index 1d17a02..4d55f42 100644 --- a/src/announce.c +++ b/src/announce.c @@ -92,7 +92,7 @@ gp_babel_nexthop_t* gp_babel_announce_nexthop_new(gp_babel_announce_t *announce, return nexthop; } -static void maintain_nexthops(gmrf_t *gmrf, gp_babel_announce_t *announce) { +static void maintain_nexthops(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_announce_t *announce) { gp_babel_nexthop_t **cur, **next; for (cur = &announce->nexthops; *cur; cur = next) { gp_babel_nexthop_t *nexthop = *cur; @@ -131,7 +131,7 @@ static void maintain_nexthops(gmrf_t *gmrf, gp_babel_announce_t *announce) { else if (gmrf_now(gmrf) > nexthop->last_update+GP_BABEL_UPDATE_REQUEST_TIMEOUT(nexthop->interval)*10 && announce->selected == nexthop) { if (!nexthop->requested_update) { gmrf_logf(gmrf, LOG_INFO, "announce about to expire, requesting update"); - // gp_babel_send_announce_request(nexthop->neigh->iface, nexthop->neigh, announce->node, announce->type, announce->key, false); + gp_babel_send_announce_request(gmrf, ctx, NULL, nexthop->neigh, &announce->node, announce->type, announce->key, false); nexthop->requested_update = true; } } @@ -172,14 +172,14 @@ gp_babel_metric_seqno_t get_metric(gmrf_t *gmrf, const gp_babel_announce_t *anno return (gp_babel_metric_seqno_t){GP_BABEL_INFINITY, 0}; } -void gp_babel_announce_update(gmrf_t *gmrf, gp_babel_announce_t *announce) { - maintain_nexthops(gmrf, announce); +void gp_babel_announce_update(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_announce_t *announce) { + maintain_nexthops(gmrf, ctx, announce); announce->selected = select_nexthop(gmrf, announce); announce->metric = get_metric(gmrf, announce); - //if (!announce->selected) - // gp_babel_send_seqno_request_for(NULL, announce); + if (!announce->selected) + gp_babel_send_seqno_request_for(gmrf, ctx, NULL, announce); /* triggered updates */ /*int diff = announce->metric.metric - announce->last_metric; @@ -191,7 +191,7 @@ void gp_babel_announce_update(gmrf_t *gmrf, gp_babel_announce_t *announce) { } */ } -void gp_babel_announce_update_nexthop(gmrf_t *gmrf, gp_babel_announce_t *announce, gp_babel_nexthop_t *nexthop, gp_babel_metric_seqno_t ms, uint16_t interval) { +void gp_babel_announce_update_nexthop(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_announce_t *announce, gp_babel_nexthop_t *nexthop, gp_babel_metric_seqno_t ms, uint16_t interval) { nexthop->metric_seqno = ms; nexthop->interval = interval; nexthop->requested_update = false; @@ -199,5 +199,5 @@ void gp_babel_announce_update_nexthop(gmrf_t *gmrf, gp_babel_announce_t *announc if (ms.metric != GP_BABEL_INFINITY) nexthop->last_update = gmrf_now(gmrf); - gp_babel_announce_update(gmrf, announce); + gp_babel_announce_update(gmrf, ctx, announce); } diff --git a/src/babel.c b/src/babel.c index 7e5e003..1ca4dd4 100644 --- a/src/babel.c +++ b/src/babel.c @@ -83,7 +83,7 @@ static void maintain_announces(gmrf_t *gmrf, gmrf_context_t *ctx) { gp_babel_announce_t *announce = *cur; next = &announce->next; - gp_babel_announce_update(gmrf, announce); + gp_babel_announce_update(gmrf, ctx, announce); if (!announce->nexthops) { *cur = *next; diff --git a/src/babel.h b/src/babel.h index cf8b435..b85438b 100644 --- a/src/babel.h +++ b/src/babel.h @@ -47,7 +47,11 @@ #define GP_BABEL_MAINTENANCE_INTERVAL GP_BABEL_HELLO_INTERVAL +#define GP_BABEL_SEQNO_REQ_HOP_LIMIT 127 + + #define GP_BABEL_UPDATE_FLAG_HAS_PAYLOAD 0x01 +#define GP_BABEL_ANNOUCE_REQ_FLAG_WITH_PAYLOAD 0x01 struct gmrf_context { @@ -119,6 +123,27 @@ struct gp_babel_nexthop { }; +void gp_babel_handle_packet(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_iface_t *iface, const gmrf_addr_t *source, const gp_babel_packet_t *packet); + +void gp_babel_send_ack(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_neigh_t *neigh, uint16_t nonce); +void gp_babel_send_hellos(gmrf_t *gmrf, gmrf_context_t *ctx); + +void gp_babel_send_update(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_iface_t *iface, gp_babel_neigh_t *neigh, gp_babel_announce_t *announce, bool with_payload); + +void gp_babel_send_announce_request(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_iface_t *iface, gp_babel_neigh_t *neigh, const gp_babel_node_id_t *node, uint16_t type, uint16_t key, bool with_payload); +void gp_babel_send_seqno_request(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_neigh_t *neigh, gp_babel_announce_t *announce, uint16_t seqno, uint8_t hop_count); + +gp_babel_announce_t* gp_babel_announce_new(gmrf_t *gmrf, gmrf_context_t *ctx); +gp_babel_announce_t* gp_babel_announce_find(gmrf_t *gmrf, gmrf_context_t *ctx, const gp_babel_node_id_t *node, uint16_t type, uint16_t key); +gp_babel_announce_t* gp_babel_announce_get(gmrf_t *gmrf, gmrf_context_t *ctx, const gp_babel_node_id_t *node, uint16_t type, uint16_t key); +void gp_babel_announce_update(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_announce_t *announce); +void gp_babel_announce_free(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_announce_t *announce); + +gp_babel_nexthop_t* gp_babel_announce_nexthop_new(gp_babel_announce_t *announce, gp_babel_neigh_t *neigh); +gp_babel_nexthop_t* gp_babel_announce_nexthop_find(const gp_babel_announce_t *announce, gp_babel_neigh_t *neigh); +void gp_babel_announce_update_nexthop(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_announce_t *announce, gp_babel_nexthop_t *nexthop, gp_babel_metric_seqno_t ms, uint16_t interval); + + static inline bool gp_babel_node_id_equal(const gp_babel_node_id_t *id1, const gp_babel_node_id_t *id2) { return (memcmp(id1->id, id2->id, GP_BABEL_NODE_ID_LENGTH) == 0); } @@ -137,7 +162,6 @@ static inline gp_babel_iface_t* gp_babel_get_iface(gmrf_context_t *ctx, gmrf_ifa return NULL; } - static inline bool gp_babel_is_metric_better(gp_babel_metric_seqno_t ms1, gp_babel_metric_seqno_t ms2) { if (ms1.metric == GP_BABEL_INFINITY) return false; @@ -162,23 +186,11 @@ static inline bool gp_babel_is_feasible(const gp_babel_announce_t *announce, gp_ return gp_babel_is_metric_better(ms, announce->feasibility_distance); } +static inline void gp_babel_send_seqno_request_for(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_neigh_t *neigh, gp_babel_announce_t *announce) { + if (announce->feasibility_distance.metric == GP_BABEL_INFINITY) + return; -void gp_babel_handle_packet(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_iface_t *iface, const gmrf_addr_t *source, const gp_babel_packet_t *packet); - -void gp_babel_send_ack(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_neigh_t *neigh, uint16_t nonce); -void gp_babel_send_hellos(gmrf_t *gmrf, gmrf_context_t *ctx); - -void gp_babel_send_update(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_iface_t *iface, gp_babel_neigh_t *neigh, gp_babel_announce_t *announce, bool with_payload); - - -gp_babel_announce_t* gp_babel_announce_new(gmrf_t *gmrf, gmrf_context_t *ctx); -gp_babel_announce_t* gp_babel_announce_find(gmrf_t *gmrf, gmrf_context_t *ctx, const gp_babel_node_id_t *node, uint16_t type, uint16_t key); -gp_babel_announce_t* gp_babel_announce_get(gmrf_t *gmrf, gmrf_context_t *ctx, const gp_babel_node_id_t *node, uint16_t type, uint16_t key); -void gp_babel_announce_update(gmrf_t *gmrf, gp_babel_announce_t *announce); -void gp_babel_announce_free(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_announce_t *announce); - -gp_babel_nexthop_t* gp_babel_announce_nexthop_new(gp_babel_announce_t *announce, gp_babel_neigh_t *neigh); -gp_babel_nexthop_t* gp_babel_announce_nexthop_find(const gp_babel_announce_t *announce, gp_babel_neigh_t *neigh); -void gp_babel_announce_update_nexthop(gmrf_t *gmrf, gp_babel_announce_t *announce, gp_babel_nexthop_t *nexthop, gp_babel_metric_seqno_t ms, uint16_t interval); + gp_babel_send_seqno_request(gmrf, ctx, neigh, announce, announce->feasibility_distance.seqno+1, GP_BABEL_SEQNO_REQ_HOP_LIMIT); +} #endif /* _GMRF_PROTO_BABEL_BABEL_H_ */ diff --git a/src/send.c b/src/send.c index 764dd2a..daaa9c3 100644 --- a/src/send.c +++ b/src/send.c @@ -52,6 +52,12 @@ static inline bool send_iface(gmrf_t *gmrf, const gp_babel_iface_t *iface, const return true; } +static inline void send_bc(gmrf_t *gmrf, gmrf_context_t *ctx, const gp_babel_packet_t *packet) { + gp_babel_iface_t *iface; + for (iface = ctx->interfaces; iface; iface = iface->next) + send_iface(gmrf, iface, packet); +} + void gp_babel_send_ack(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_neigh_t *neigh, uint16_t nonce) { gp_babel_packet_buf_t *buf = gp_babel_packet_alloca(GP_BABEL_PACKET_MAX); @@ -198,3 +204,44 @@ void gp_babel_send_update(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_iface_t *i send_iface(gmrf, iface, &buf->packet); } } + +void gp_babel_send_announce_request(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_iface_t *iface, gp_babel_neigh_t *neigh, const gp_babel_node_id_t *node, uint16_t type, uint16_t key, bool with_payload) { + gp_babel_packet_buf_t *buf = gp_babel_packet_alloca(GP_BABEL_PACKET_MAX); + + gp_babel_tlv_announce_req_t *req = gp_babel_tlv_add(buf, TLV_ANNOUNCE_REQ, sizeof(gp_babel_tlv_announce_req_t)); + if (!req) + return; + + req->node = *node; + req->flags = 0; + req->reserved = 0; + req->type = htons(type); + req->key = htons(key); + + if (with_payload) + req->flags |= GP_BABEL_ANNOUCE_REQ_FLAG_WITH_PAYLOAD; + + if (neigh) + send_neigh(gmrf, neigh, &buf->packet); + else + send_iface(gmrf, iface, &buf->packet); +} + +void gp_babel_send_seqno_request(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_neigh_t *neigh, gp_babel_announce_t *announce, uint16_t seqno, uint8_t hop_count) { + gp_babel_packet_buf_t *buf = gp_babel_packet_alloca(GP_BABEL_PACKET_MAX); + + gp_babel_tlv_seqno_req_t *req = gp_babel_tlv_add(buf, TLV_SEQNO_REQ, sizeof(gp_babel_tlv_seqno_req_t)); + if (!req) + return; + + req->seqno = htons(seqno); + req->hop_count = hop_count; + req->node = announce->node; + req->type = htons(announce->type); + req->key = htons(announce->key); + + if (neigh) + send_neigh(gmrf, neigh, &buf->packet); + else + send_bc(gmrf, ctx, &buf->packet); +} diff --git a/src/tlv_types.c b/src/tlv_types.c index d3f2d92..cc380ea 100644 --- a/src/tlv_types.c +++ b/src/tlv_types.c @@ -182,16 +182,16 @@ static void handle_tlv_update(gmrf_t *gmrf, gmrf_context_t *ctx, const gp_babel_ } else { if (!feasible && nexthop == announce->selected) { - gmrf_logf(gmrf, LOG_DEBUG, "need new seqno"); - // gp_babel_send_seqno_request_for(neigh, announce); + gmrf_logf(gmrf, LOG_DEBUG, "requesting new seqno"); + gp_babel_send_seqno_request_for(gmrf, ctx, neigh, announce); nexthop = NULL; } } if (!feasible && nexthop && nexthop != announce->selected) { if (ms.metric + gp_babel_neigh_get_cost(gmrf, neigh) < announce->metric.metric) { - gmrf_logf(gmrf, LOG_DEBUG, "need new seqno"); - // gp_babel_send_seqno_request_for(neigh, announce); + gmrf_logf(gmrf, LOG_DEBUG, "requesting new seqno"); + gp_babel_send_seqno_request_for(gmrf, ctx, neigh, announce); } } @@ -205,8 +205,8 @@ static void handle_tlv_update(gmrf_t *gmrf, gmrf_context_t *ctx, const gp_babel_ announce->len = 0xff; /* request payload */ - //if (nexthop) - // gp_babel_send_announce_request(arg->iface, neigh, announce->node, announce->type, announce->key, true); + if (nexthop) + gp_babel_send_announce_request(gmrf, ctx, NULL, neigh, &announce->node, announce->type, announce->key, true); } } @@ -215,7 +215,7 @@ static void handle_tlv_update(gmrf_t *gmrf, gmrf_context_t *ctx, const gp_babel_ gmrf_logf(gmrf, LOG_DEBUG, "the update was accepted."); - gp_babel_announce_update_nexthop(gmrf, announce, nexthop, ms, ntohs(tlv_update->interval)); + gp_babel_announce_update_nexthop(gmrf, ctx, announce, nexthop, ms, ntohs(tlv_update->interval)); } static void handle_tlv(gmrf_t *gmrf, gmrf_context_t *ctx, gp_babel_tlv_type_t type, const void *data, size_t len, void *arg) { -- cgit v1.2.3