1998-07-09 19:39:04 +00:00
|
|
|
/*
|
2015-10-05 10:14:50 +00:00
|
|
|
* BIRD -- Routing Information Protocol (RIP)
|
1999-10-11 14:19:29 +00:00
|
|
|
*
|
2015-10-05 10:14:50 +00:00
|
|
|
* (c) 1998--1999 Pavel Machek <pavel@ucw.cz>
|
|
|
|
* (c) 2004--2013 Ondrej Filip <feela@network.cz>
|
|
|
|
* (c) 2009--2015 Ondrej Zajicek <santiago@crfreenet.org>
|
|
|
|
* (c) 2009--2015 CZ.NIC z.s.p.o.
|
|
|
|
*
|
|
|
|
* Can be freely distributed and used under the terms of the GNU GPL.
|
1998-07-09 19:39:04 +00:00
|
|
|
*/
|
|
|
|
|
2015-10-05 10:14:50 +00:00
|
|
|
#ifndef _BIRD_RIP_H_
|
|
|
|
#define _BIRD_RIP_H_
|
|
|
|
|
2023-10-24 07:52:09 +00:00
|
|
|
#include <pthread.h>
|
2015-10-05 10:14:50 +00:00
|
|
|
#include "nest/bird.h"
|
|
|
|
#include "nest/cli.h"
|
|
|
|
#include "nest/iface.h"
|
|
|
|
#include "nest/protocol.h"
|
2022-03-31 17:09:38 +00:00
|
|
|
#include "nest/rt.h"
|
1999-05-26 14:37:47 +00:00
|
|
|
#include "nest/password.h"
|
2000-03-22 14:26:03 +00:00
|
|
|
#include "nest/locks.h"
|
2015-10-05 10:14:50 +00:00
|
|
|
#include "nest/bfd.h"
|
|
|
|
#include "lib/lists.h"
|
|
|
|
#include "lib/resource.h"
|
|
|
|
#include "lib/socket.h"
|
|
|
|
#include "lib/string.h"
|
2017-11-28 16:43:20 +00:00
|
|
|
#include "lib/timer.h"
|
1998-12-22 19:41:04 +00:00
|
|
|
|
1999-05-31 19:16:22 +00:00
|
|
|
|
2015-10-05 10:14:50 +00:00
|
|
|
#define RIP_V1 1
|
|
|
|
#define RIP_V2 2
|
2012-03-15 11:38:08 +00:00
|
|
|
|
2015-10-05 10:14:50 +00:00
|
|
|
#define RIP_PORT 520 /* RIP for IPv4 */
|
|
|
|
#define RIP_NG_PORT 521 /* RIPng */
|
2012-03-15 11:38:08 +00:00
|
|
|
|
2015-10-05 10:14:50 +00:00
|
|
|
#define RIP_MAX_PKT_LENGTH 532 /* 512 + IP4_HEADER_LENGTH */
|
2016-10-26 14:07:45 +00:00
|
|
|
#define RIP_AUTH_TAIL_LENGTH 4 /* Without auth_data */
|
1999-08-18 13:19:33 +00:00
|
|
|
|
2015-10-05 10:14:50 +00:00
|
|
|
#define RIP_DEFAULT_ECMP_LIMIT 16
|
|
|
|
#define RIP_DEFAULT_INFINITY 16
|
2017-06-20 12:30:44 +00:00
|
|
|
#define RIP_DEFAULT_UPDATE_TIME (30 S_)
|
|
|
|
#define RIP_DEFAULT_TIMEOUT_TIME (180 S_)
|
|
|
|
#define RIP_DEFAULT_GARBAGE_TIME (120 S_)
|
2020-02-21 01:35:50 +00:00
|
|
|
#define RIP_DEFAULT_RXMT_TIME (1 S_)
|
1998-07-28 21:44:11 +00:00
|
|
|
|
1998-10-26 15:35:19 +00:00
|
|
|
|
2015-10-05 10:14:50 +00:00
|
|
|
struct rip_config
|
|
|
|
{
|
|
|
|
struct proto_config c;
|
|
|
|
list patt_list; /* List of iface configs (struct rip_iface_config) */
|
1998-07-09 19:39:04 +00:00
|
|
|
|
2015-10-05 10:14:50 +00:00
|
|
|
u8 rip2; /* RIPv2 (IPv4) or RIPng (IPv6) */
|
|
|
|
u8 ecmp; /* Maximum number of nexthops in ECMP route, or 0 */
|
|
|
|
u8 infinity; /* Maximum metric value, representing infinity */
|
|
|
|
|
2017-06-20 12:30:44 +00:00
|
|
|
btime min_timeout_time; /* Minimum of interface timeout_time */
|
|
|
|
btime max_garbage_time; /* Maximum of interface garbage_time */
|
1998-07-09 19:39:04 +00:00
|
|
|
};
|
|
|
|
|
2015-10-05 10:14:50 +00:00
|
|
|
struct rip_iface_config
|
|
|
|
{
|
|
|
|
struct iface_patt i;
|
|
|
|
ip_addr address; /* Configured dst address */
|
|
|
|
u16 port; /* Src+dst port */
|
|
|
|
u8 metric; /* Incoming metric */
|
|
|
|
u8 mode; /* Interface mode (RIP_IM_*) */
|
|
|
|
u8 passive; /* Passive iface - no packets are sent */
|
|
|
|
u8 version; /* RIP version used for outgoing packets */
|
|
|
|
u8 version_only; /* FIXXX */
|
|
|
|
u8 split_horizon; /* Split horizon is used in route updates */
|
|
|
|
u8 poison_reverse; /* Poisoned reverse is used in route updates */
|
|
|
|
u8 check_zero; /* Validation of RIPv1 reserved fields */
|
|
|
|
u8 ecmp_weight; /* Weight for ECMP routes*/
|
|
|
|
u8 auth_type; /* Authentication type (RIP_AUTH_*) */
|
|
|
|
u8 ttl_security; /* bool + 2 for TX only (send, but do not check on RX) */
|
|
|
|
u8 check_link; /* Whether iface link change is used */
|
2020-02-21 01:35:50 +00:00
|
|
|
u8 demand_circuit; /* Use demand circuit extensions (RFC 2091) */
|
2015-10-05 10:14:50 +00:00
|
|
|
u8 bfd; /* Use BFD on iface */
|
|
|
|
u16 rx_buffer; /* RX buffer size, 0 for MTU */
|
|
|
|
u16 tx_length; /* TX packet length limit (including headers), 0 for MTU */
|
|
|
|
int tx_tos;
|
|
|
|
int tx_priority;
|
2017-06-20 12:30:44 +00:00
|
|
|
btime update_time; /* Periodic update interval */
|
|
|
|
btime timeout_time; /* Route expiration timeout */
|
|
|
|
btime garbage_time; /* Unreachable entry GC timeout */
|
2020-02-21 01:35:50 +00:00
|
|
|
btime rxmt_time; /* Retransmit timeout for demand circuit */
|
2015-10-05 10:14:50 +00:00
|
|
|
list *passwords; /* Passwords for authentication */
|
1998-07-09 19:39:04 +00:00
|
|
|
};
|
2015-10-05 10:14:50 +00:00
|
|
|
|
|
|
|
struct rip_proto
|
|
|
|
{
|
|
|
|
struct proto p;
|
|
|
|
struct fib rtable; /* Internal routing table */
|
|
|
|
list iface_list; /* List of interfaces (struct rip_iface) */
|
|
|
|
slab *rte_slab; /* Slab for internal routes (struct rip_rte) */
|
|
|
|
timer *timer; /* Main protocol timer */
|
|
|
|
|
2015-12-21 02:27:41 +00:00
|
|
|
u8 rip2; /* RIPv2 (IPv4) or RIPng (IPv6) */
|
2015-10-05 10:14:50 +00:00
|
|
|
u8 ecmp; /* Maximum number of nexthops in ECMP route, or 0 */
|
|
|
|
u8 infinity; /* Maximum metric value, representing infinity */
|
|
|
|
u8 triggered; /* Logical AND of interface want_triggered values */
|
|
|
|
u8 rt_reload; /* Route reload is scheduled */
|
|
|
|
|
|
|
|
struct tbf log_pkt_tbf; /* TBF for packet messages */
|
|
|
|
struct tbf log_rte_tbf; /* TBF for RTE messages */
|
2023-10-24 07:52:09 +00:00
|
|
|
struct channel_import_request *cir; /* Trie for partial reload */
|
|
|
|
pthread_mutex_t mutex; /* Mutex for partial reload */
|
1999-10-11 14:19:29 +00:00
|
|
|
};
|
1998-07-09 19:39:04 +00:00
|
|
|
|
2015-10-05 10:14:50 +00:00
|
|
|
struct rip_iface
|
|
|
|
{
|
|
|
|
node n;
|
|
|
|
struct rip_proto *rip;
|
|
|
|
struct iface *iface; /* Underyling core interface */
|
|
|
|
struct rip_iface_config *cf; /* Related config, must be updated in reconfigure */
|
|
|
|
struct object_lock *lock; /* Interface lock */
|
|
|
|
timer *timer; /* Interface timer */
|
2020-02-21 01:35:50 +00:00
|
|
|
timer *rxmt_timer; /* Retransmission timer */
|
2015-10-05 10:14:50 +00:00
|
|
|
sock *sk; /* UDP socket */
|
|
|
|
|
|
|
|
u8 up; /* Interface is active */
|
|
|
|
u8 csn_ready; /* Nonzero CSN can be used */
|
|
|
|
u16 tx_plen; /* Max TX packet data length */
|
|
|
|
u32 csn; /* Last used crypto sequence number */
|
|
|
|
ip_addr addr; /* Destination multicast/broadcast address */
|
|
|
|
list neigh_list; /* List of iface neighbors (struct rip_neighbor) */
|
|
|
|
|
|
|
|
/* Update scheduling */
|
2017-06-20 12:30:44 +00:00
|
|
|
btime next_regular; /* Next time when regular update should be called */
|
|
|
|
btime next_triggered; /* Next time when triggerd update may be called */
|
|
|
|
btime want_triggered; /* Nonzero if triggered update is scheduled */
|
2015-10-05 10:14:50 +00:00
|
|
|
|
|
|
|
/* Active update */
|
|
|
|
int tx_active; /* Update session is active */
|
2020-02-21 01:35:50 +00:00
|
|
|
int tx_waiting;
|
2015-10-05 10:14:50 +00:00
|
|
|
ip_addr tx_addr; /* Update session destination address */
|
2017-06-20 12:30:44 +00:00
|
|
|
btime tx_changed; /* Minimal changed time for triggered update */
|
2015-10-05 10:14:50 +00:00
|
|
|
struct fib_iterator tx_fit; /* FIB iterator in RIP routing table (p.rtable) */
|
2020-02-21 01:35:50 +00:00
|
|
|
struct fib_iterator tx_done; /* FIB iterator for acked routes (p.rtable) */
|
|
|
|
|
|
|
|
/* Update message */
|
|
|
|
u8 tx_pending;
|
|
|
|
u8 tx_flush;
|
|
|
|
u16 tx_seqnum;
|
|
|
|
|
|
|
|
u8 req_pending;
|
1999-05-31 17:12:38 +00:00
|
|
|
};
|
|
|
|
|
2015-10-05 10:14:50 +00:00
|
|
|
struct rip_neighbor
|
|
|
|
{
|
|
|
|
node n;
|
|
|
|
struct rip_iface *ifa; /* Associated interface, may be NULL if stale */
|
|
|
|
struct neighbor *nbr; /* Associaded core neighbor, may be NULL if stale */
|
|
|
|
struct bfd_request *bfd_req; /* BFD request, if BFD is used */
|
2017-06-20 12:30:44 +00:00
|
|
|
btime last_seen; /* Time of last received and accepted message */
|
2015-10-05 10:14:50 +00:00
|
|
|
u32 uc; /* Use count, number of routes linking the neighbor */
|
|
|
|
u32 csn; /* Last received crypto sequence number */
|
1999-05-31 19:16:22 +00:00
|
|
|
};
|
|
|
|
|
2015-10-05 10:14:50 +00:00
|
|
|
struct rip_entry
|
|
|
|
{
|
|
|
|
struct rip_rte *routes; /* List of incoming routes */
|
1998-07-09 19:39:04 +00:00
|
|
|
|
2015-10-05 10:14:50 +00:00
|
|
|
u8 valid; /* Entry validity state (RIP_ENTRY_*) */
|
|
|
|
u8 metric; /* Outgoing route metric */
|
|
|
|
u16 tag; /* Outgoing route tag */
|
2020-03-14 16:04:49 +00:00
|
|
|
struct iface *from; /* Outgoing route from, NULL if from proto */
|
2015-10-05 10:14:50 +00:00
|
|
|
struct iface *iface; /* Outgoing route iface (for next hop) */
|
|
|
|
ip_addr next_hop; /* Outgoing route next hop */
|
1998-07-09 19:39:04 +00:00
|
|
|
|
2017-06-20 12:30:44 +00:00
|
|
|
btime changed; /* Last time when the outgoing route metric changed */
|
2015-11-05 11:48:52 +00:00
|
|
|
|
|
|
|
struct fib_node n;
|
1998-07-09 19:39:04 +00:00
|
|
|
};
|
|
|
|
|
2015-10-05 10:14:50 +00:00
|
|
|
struct rip_rte
|
|
|
|
{
|
|
|
|
struct rip_rte *next;
|
1998-07-09 19:39:04 +00:00
|
|
|
|
2015-10-05 10:14:50 +00:00
|
|
|
struct rip_neighbor *from; /* Advertising router */
|
|
|
|
ip_addr next_hop; /* Route next hop (iface is from->nbr->iface) */
|
|
|
|
u16 metric; /* Route metric (after increase) */
|
|
|
|
u16 tag; /* Route tag */
|
|
|
|
|
2017-06-20 12:30:44 +00:00
|
|
|
btime expires; /* Time of route expiration */
|
1999-01-12 16:40:55 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-10-05 10:14:50 +00:00
|
|
|
#define RIP_AUTH_NONE 0
|
|
|
|
#define RIP_AUTH_PLAIN 2
|
|
|
|
#define RIP_AUTH_CRYPTO 3
|
1998-10-26 15:35:19 +00:00
|
|
|
|
2015-10-05 10:14:50 +00:00
|
|
|
#define RIP_IM_MULTICAST 1
|
|
|
|
#define RIP_IM_BROADCAST 2
|
1999-02-15 13:34:43 +00:00
|
|
|
|
2015-10-05 10:14:50 +00:00
|
|
|
#define RIP_ENTRY_DUMMY 0 /* Only used to store list of incoming routes */
|
|
|
|
#define RIP_ENTRY_VALID 1 /* Valid outgoing route */
|
|
|
|
#define RIP_ENTRY_STALE 2 /* Stale outgoing route, waiting for GC */
|
2023-09-27 14:29:44 +00:00
|
|
|
#define RIP_ENTRY_REFEEDING 3 /* Route valid until feed ends */
|
1998-07-09 19:39:04 +00:00
|
|
|
|
2015-10-05 10:14:50 +00:00
|
|
|
static inline int rip_is_v2(struct rip_proto *p)
|
|
|
|
{ return p->rip2; }
|
|
|
|
|
|
|
|
static inline int rip_is_ng(struct rip_proto *p)
|
|
|
|
{ return ! p->rip2; }
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
rip_reset_tx_session(struct rip_proto *p, struct rip_iface *ifa)
|
|
|
|
{
|
|
|
|
if (ifa->tx_active)
|
|
|
|
{
|
|
|
|
FIB_ITERATE_UNLINK(&ifa->tx_fit, &p->rtable);
|
2020-02-21 01:35:50 +00:00
|
|
|
FIB_ITERATE_UNLINK(&ifa->tx_done, &p->rtable);
|
2015-10-05 10:14:50 +00:00
|
|
|
ifa->tx_active = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* rip.c */
|
2015-11-05 11:48:52 +00:00
|
|
|
void rip_update_rte(struct rip_proto *p, net_addr *n, struct rip_rte *new);
|
|
|
|
void rip_withdraw_rte(struct rip_proto *p, net_addr *n, struct rip_neighbor *from);
|
2020-02-21 01:35:50 +00:00
|
|
|
void rip_flush_table(struct rip_proto *p, struct rip_neighbor *n);
|
2015-10-05 10:14:50 +00:00
|
|
|
struct rip_neighbor * rip_get_neighbor(struct rip_proto *p, ip_addr *a, struct rip_iface *ifa);
|
|
|
|
void rip_update_bfd(struct rip_proto *p, struct rip_neighbor *n);
|
2020-04-08 20:25:15 +00:00
|
|
|
void rip_show_interfaces(struct proto *P, const char *iff);
|
|
|
|
void rip_show_neighbors(struct proto *P, const char *iff);
|
2015-10-05 10:14:50 +00:00
|
|
|
|
|
|
|
/* packets.c */
|
|
|
|
void rip_send_request(struct rip_proto *p, struct rip_iface *ifa);
|
2017-06-20 12:30:44 +00:00
|
|
|
void rip_send_table(struct rip_proto *p, struct rip_iface *ifa, ip_addr addr, btime changed);
|
2020-03-14 16:04:49 +00:00
|
|
|
int rip_send_flush(struct rip_proto *p, struct rip_iface *ifa);
|
2020-02-21 01:35:50 +00:00
|
|
|
void rip_rxmt_timeout(timer *t);
|
2015-10-05 10:14:50 +00:00
|
|
|
int rip_open_socket(struct rip_iface *ifa);
|
1999-05-11 09:53:45 +00:00
|
|
|
|
|
|
|
|
2015-10-05 10:14:50 +00:00
|
|
|
#endif
|