160 lines
4.3 KiB
C
160 lines
4.3 KiB
C
/*
|
|
Copyright (c) 2012, Matthias Schiffer <mschiffer@universe-factory.net>
|
|
All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions are met:
|
|
|
|
1. Redistributions of source code must retain the above copyright notice,
|
|
this list of conditions and the following disclaimer.
|
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
this list of conditions and the following disclaimer in the documentation
|
|
and/or other materials provided with the distribution.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
|
|
#ifndef _FFD_FFD_H_
|
|
#define _FFD_FFD_H_
|
|
|
|
#include "util.h"
|
|
#include "netif.h"
|
|
|
|
#include <net/if.h>
|
|
|
|
|
|
#define FFD_PACKET_MAX 1000
|
|
|
|
#define FFD_PROTO 0xffd
|
|
|
|
#define FFD_HELLO_INTERVAL 400
|
|
#define FFD_IHU_INTERVAL (3*FFD_HELLO_INTERVAL)
|
|
|
|
#define FFD_UPDATE_INTERVAL 400
|
|
|
|
|
|
#define FFD_UPDATE_WITH_DATA 0x01
|
|
|
|
|
|
typedef struct __attribute__((packed)) _ffd_node_id_t {
|
|
uint8_t id[8];
|
|
} ffd_node_id_t;
|
|
|
|
|
|
#define FFD_NODE_ID_UNSPEC ((ffd_node_id_t){})
|
|
|
|
|
|
static inline bool ffd_is_node_id_unspec(const ffd_node_id_t *node) {
|
|
const uint8_t *id = node->id;
|
|
|
|
if (id[0]||id[1]||id[2]||id[3]||id[4]||id[5]||id[6]||id[7])
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
|
|
static inline bool ffd_are_node_ids_equal(const ffd_node_id_t *id1, const ffd_node_id_t *id2) {
|
|
const uint8_t *a = id1->id;
|
|
const uint8_t *b = id2->id;
|
|
|
|
return (a[0]==b[0] && a[1]==b[1] && a[2]==b[2] && a[3]==b[3]
|
|
&& a[4]==b[4] && a[5]==b[5] && a[6]==b[6] && a[7]==b[7]);
|
|
}
|
|
|
|
|
|
typedef struct _ffd_metric_seqno_t {
|
|
uint16_t metric;
|
|
uint16_t seqno;
|
|
} ffd_metric_seqno_t;
|
|
|
|
#define FFD_IS_INFINITY(m) ((m).metric == 0xffff)
|
|
|
|
typedef struct _ffd_nexthop_t {
|
|
struct _ffd_nexthop_t *next;
|
|
|
|
struct _ffd_neigh_t *neigh;
|
|
ffd_metric_seqno_t metric_seqno;
|
|
|
|
struct timespec last_update;
|
|
uint16_t interval;
|
|
} ffd_nexthop_t;
|
|
|
|
typedef struct _ffd_announce_t {
|
|
struct _ffd_announce_t *next;
|
|
|
|
ffd_node_id_t node;
|
|
uint16_t type;
|
|
uint16_t key;
|
|
|
|
ffd_metric_seqno_t feasibility_distance;
|
|
|
|
ffd_nexthop_t *selected;
|
|
ffd_nexthop_t *nexthop_list;
|
|
|
|
/* an incomplete announcement is specified by a len value of 0xff with NULL data */
|
|
uint8_t len;
|
|
uint8_t *data;
|
|
} ffd_announce_t;
|
|
|
|
typedef struct _ffd_neigh_t {
|
|
struct _ffd_neigh_t *next;
|
|
|
|
/* for actual routing, we'd also have to link back to the iface
|
|
this neighbour belongs to */
|
|
eth_addr_t addr;
|
|
|
|
uint16_t hello_log;
|
|
uint16_t hello_interval;
|
|
uint16_t last_seqno;
|
|
struct timespec last_hello;
|
|
struct timespec last_ihu;
|
|
|
|
uint16_t txcost;
|
|
} ffd_neigh_t;
|
|
|
|
typedef struct _ffd_iface_t {
|
|
struct _ffd_iface_t *next;
|
|
|
|
unsigned ifindex;
|
|
char name[IF_NAMESIZE];
|
|
eth_addr_t addr;
|
|
|
|
netif_type_t type;
|
|
uint16_t seqno;
|
|
|
|
ffd_neigh_t *neigh_list;
|
|
} ffd_iface_t;
|
|
|
|
|
|
extern const eth_addr_t ffd_addr;
|
|
|
|
extern ffd_node_id_t self;
|
|
|
|
extern ffd_iface_t *iface_list;
|
|
extern ffd_announce_t *announce_list;
|
|
|
|
extern int sockfd;
|
|
extern struct timespec now;
|
|
|
|
|
|
bool ffd_is_feasible(const ffd_announce_t *announce, ffd_metric_seqno_t ms);
|
|
ffd_metric_seqno_t ffd_announce_get_metric(const ffd_announce_t *announce);
|
|
void ffd_announce_update(ffd_announce_t *announce, ffd_nexthop_t *nexthop, ffd_metric_seqno_t ms, uint16_t interval);
|
|
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);
|
|
|
|
#endif /* _FFD_FFD_H_ */
|