1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
|
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* pim_autorp.h: PIM Auto RP handling related
*
* Copyright (C) 20224 ATCorp.
* Nathan Bahr
*/
#ifndef __PIM_AUTORP_H__
#define __PIM_AUTORP_H__
#include <typesafe.h>
#define AUTORP_VERSION 1
#define AUTORP_ANNOUNCEMENT_TYPE 1
#define AUTORP_DISCOVERY_TYPE 2
#define AUTORP_PIM_VUNKNOWN 0
#define AUTORP_PIM_V1 1
#define AUTORP_PIM_V2 2
#define AUTORP_PIM_V1_2 3
#define DEFAULT_AUTORP_ANNOUNCE_INTERVAL 60
#define DEFAULT_AUTORP_ANNOUNCE_SCOPE 31
#define DEFAULT_AUTORP_ANNOUNCE_HOLDTIME -1
#define DEFAULT_AUTORP_DISCOVERY_INTERVAL 60
#define DEFAULT_AUTORP_DISCOVERY_SCOPE 31
#define DEFAULT_AUTORP_DISCOVERY_HOLDTIME 180
PREDECL_SORTLIST_UNIQ(pim_autorp_rp);
PREDECL_SORTLIST_UNIQ(pim_autorp_grppfix);
struct autorp_pkt_grp {
#if __BYTE_ORDER == __LITTLE_ENDIAN
uint8_t negprefix : 1;
uint8_t reserved : 7;
#elif __BYTE_ORDER == __BIG_ENDIAN
uint8_t reserved : 7;
uint8_t negprefix : 1;
#else
#error "Please fix <bits/endian.h>"
#endif
uint8_t masklen;
uint32_t addr;
} __attribute__((__packed__));
struct autorp_pkt_rp {
uint32_t addr;
#if __BYTE_ORDER == __LITTLE_ENDIAN
uint8_t pimver : 2;
uint8_t reserved : 6;
#elif __BYTE_ORDER == __BIG_ENDIAN
uint8_t reserved : 6;
uint8_t pimver : 2;
#else
#error "Please fix <bits/endian.h>"
#endif
uint8_t grpcnt;
} __attribute__((__packed__));
struct autorp_pkt_hdr {
#if __BYTE_ORDER == __LITTLE_ENDIAN
uint8_t type : 4;
uint8_t version : 4;
#elif __BYTE_ORDER == __BIG_ENDIAN
uint8_t version : 4;
uint8_t type : 4;
#else
#error "Please fix <bits/endian.h>"
#endif
uint8_t rpcnt;
uint16_t holdtime;
uint32_t reserved;
} __attribute__((__packed__));
#define MIN_AUTORP_PKT_SZ \
(sizeof(struct autorp_pkt_hdr) + sizeof(struct autorp_pkt_rp) + \
sizeof(struct autorp_pkt_grp))
struct pim_autorp_rp {
struct pim_autorp *autorp;
struct in_addr addr;
uint16_t holdtime;
struct event *hold_timer;
struct prefix grp;
char grplist[32];
struct pim_autorp_grppfix_head grp_pfix_list;
struct pim_autorp_rp_item item;
};
struct pim_autorp_grppfix {
struct prefix grp;
struct in_addr rp;
bool negative;
struct pim_autorp_grppfix_item item;
};
struct pim_autorp {
/* backpointer to pim instance */
struct pim_instance *pim;
/* UDP socket bound to AutoRP port, used for sending and receiving all AutoRP packets */
int sock;
/* Event for reading AutoRP packets */
struct event *read_event;
/* Event for sending announcement packets */
struct event *announce_timer;
/* Event for sending discovery packets*/
struct event *send_discovery_timer;
/* Flag enabling reading discovery packets */
bool do_discovery;
/* Flag enabling mapping agent (reading announcements and sending discovery)*/
bool send_rp_discovery;
/* Flag indicating if we are sending discovery messages (true) or if a higher IP mapping
* agent preemptied our sending (false)
*/
bool mapping_agent_active;
/* List of RP's in received discovery packets */
struct pim_autorp_rp_head discovery_rp_list;
/* List of configured candidate RP's to send in announcement packets */
struct pim_autorp_rp_head candidate_rp_list;
/* List of announced RP's to send in discovery packets */
struct pim_autorp_rp_head mapping_rp_list;
/* List of the last advertised RP's, via mapping agent discovery
* This is only filled if a discovery message was sent
*/
struct pim_autorp_rp_head advertised_rp_list;
/* Packet parameters for sending announcement packets */
uint8_t announce_scope;
uint16_t announce_interval;
int32_t announce_holdtime;
/* Pre-built announcement packet, only changes when configured RP's or packet parameters change */
uint8_t *announce_pkt;
uint16_t announce_pkt_sz;
/* Packet parameters for sending discovery packets */
uint8_t discovery_scope;
uint16_t discovery_interval;
uint16_t discovery_holdtime;
struct cand_addrsel mapping_agent_addrsel;
};
#define AUTORP_GRPLEN 6
#define AUTORP_RPLEN 6
#define AUTORP_HDRLEN 8
void pim_autorp_prefix_list_update(struct pim_instance *pim, struct prefix_list *plist);
bool pim_autorp_rm_candidate_rp(struct pim_instance *pim, pim_addr rpaddr);
void pim_autorp_add_candidate_rp_group(struct pim_instance *pim, pim_addr rpaddr,
struct prefix group);
bool pim_autorp_rm_candidate_rp_group(struct pim_instance *pim, pim_addr rpaddr,
struct prefix group);
void pim_autorp_add_candidate_rp_plist(struct pim_instance *pim, pim_addr rpaddr, const char *plist);
bool pim_autorp_rm_candidate_rp_plist(struct pim_instance *pim, pim_addr rpaddr, const char *plist);
void pim_autorp_announce_scope(struct pim_instance *pim, uint8_t scope);
void pim_autorp_announce_interval(struct pim_instance *pim, uint16_t interval);
void pim_autorp_announce_holdtime(struct pim_instance *pim, int32_t holdtime);
void pim_autorp_send_discovery_apply(struct pim_autorp *autorp);
void pim_autorp_add_ifp(struct interface *ifp);
void pim_autorp_rm_ifp(struct interface *ifp);
void pim_autorp_start_discovery(struct pim_instance *pim);
void pim_autorp_stop_discovery(struct pim_instance *pim);
void pim_autorp_init(struct pim_instance *pim);
void pim_autorp_finish(struct pim_instance *pim);
int pim_autorp_config_write(struct pim_instance *pim, struct vty *vty);
void pim_autorp_show_autorp(struct vty *vty, struct pim_instance *pim, const char *component,
json_object *json);
#endif
|