]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_mpls_openbsd.c
*: remove dead code
[mirror_frr.git] / zebra / zebra_mpls_openbsd.c
CommitLineData
d3e2c74a
RW
1#include <zebra.h>
2#include <netmpls/mpls.h>
3#include "zebra/rt.h"
4#include "zebra/zebra_mpls.h"
5#include "zebra/debug.h"
6
7#include "privs.h"
8#include "prefix.h"
9#include "interface.h"
10#include "log.h"
11
12extern struct zebra_privs_t zserv_privs;
13
14struct {
15 u_int32_t rtseq;
16 int fd;
17} kr_state;
18
19static int
20kernel_send_rtmsg (int action, mpls_label_t in_label, zebra_nhlfe_t *nhlfe)
21{
22 struct iovec iov[5];
23 struct rt_msghdr hdr;
24 struct sockaddr_mpls sa_label_in, sa_label_out;
25 struct sockaddr_in nexthop;
26 int iovcnt = 0;
27 int ret;
28
29 if (IS_ZEBRA_DEBUG_KERNEL)
30 zlog_debug ("kernel_send_rtmsg: 0x%x, label=%u", action, in_label);
31
32 /* initialize header */
33 bzero(&hdr, sizeof (hdr));
34 hdr.rtm_version = RTM_VERSION;
35
36 hdr.rtm_type = action;
37 hdr.rtm_flags = RTF_UP;
38 hdr.rtm_fmask = RTF_MPLS;
39 hdr.rtm_seq = kr_state.rtseq++; /* overflow doesn't matter */
40 hdr.rtm_msglen = sizeof (hdr);
41 hdr.rtm_hdrlen = sizeof (struct rt_msghdr);
42 hdr.rtm_priority = 0;
43 /* adjust iovec */
44 iov[iovcnt].iov_base = &hdr;
45 iov[iovcnt++].iov_len = sizeof (hdr);
46
47 /* in label */
48 bzero(&sa_label_in, sizeof (sa_label_in));
49 sa_label_in.smpls_len = sizeof (sa_label_in);
50 sa_label_in.smpls_family = AF_MPLS;
51 sa_label_in.smpls_label = htonl(in_label << MPLS_LABEL_OFFSET);
52 /* adjust header */
53 hdr.rtm_flags |= RTF_MPLS | RTF_MPATH;
54 hdr.rtm_addrs |= RTA_DST;
55 hdr.rtm_msglen += sizeof (sa_label_in);
56 /* adjust iovec */
57 iov[iovcnt].iov_base = &sa_label_in;
58 iov[iovcnt++].iov_len = sizeof (sa_label_in);
59
60 /* nexthop */
61 bzero(&nexthop, sizeof (nexthop));
62 nexthop.sin_len = sizeof (nexthop);
63 nexthop.sin_family = AF_INET;
64 nexthop.sin_addr = nhlfe->nexthop->gate.ipv4;
65 /* adjust header */
66 hdr.rtm_flags |= RTF_GATEWAY;
67 hdr.rtm_addrs |= RTA_GATEWAY;
68 hdr.rtm_msglen += sizeof (nexthop);
69 /* adjust iovec */
70 iov[iovcnt].iov_base = &nexthop;
71 iov[iovcnt++].iov_len = sizeof (nexthop);
72
73 /* If action is RTM_DELETE we have to get rid of MPLS infos */
74 if (action != RTM_DELETE)
75 {
76 bzero(&sa_label_out, sizeof (sa_label_out));
77 sa_label_out.smpls_len = sizeof (sa_label_out);
78 sa_label_out.smpls_family = AF_MPLS;
79 sa_label_out.smpls_label =
80 htonl(nhlfe->nexthop->nh_label->label[0] << MPLS_LABEL_OFFSET);
81 /* adjust header */
82 hdr.rtm_addrs |= RTA_SRC;
83 hdr.rtm_flags |= RTF_MPLS;
84 hdr.rtm_msglen += sizeof (sa_label_out);
85 /* adjust iovec */
86 iov[iovcnt].iov_base = &sa_label_out;
87 iov[iovcnt++].iov_len = sizeof (sa_label_out);
88
89 if (nhlfe->nexthop->nh_label->label[0] == MPLS_LABEL_IMPLNULL)
90 hdr.rtm_mpls = MPLS_OP_POP;
91 else
92 hdr.rtm_mpls = MPLS_OP_SWAP;
93 }
94
95 if (zserv_privs.change(ZPRIVS_RAISE))
96 zlog_err ("Can't raise privileges");
97 ret = writev (kr_state.fd, iov, iovcnt);
98 if (zserv_privs.change(ZPRIVS_LOWER))
99 zlog_err ("Can't lower privileges");
100
101 if (ret == -1)
102 zlog_err ("kernel_send_rtmsg: %s", safe_strerror (errno));
103
104 return ret;
105}
106
107static int
108kernel_lsp_cmd (int action, zebra_lsp_t *lsp)
109{
110 zebra_nhlfe_t *nhlfe;
111 struct nexthop *nexthop = NULL;
112 int nexthop_num = 0;
113
114 for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next)
115 {
116 nexthop = nhlfe->nexthop;
117 if (!nexthop)
118 continue;
119
120 if (MULTIPATH_NUM != 0 && nexthop_num >= MULTIPATH_NUM)
121 break;
122
123 /* XXX */
124 if (NHLFE_FAMILY(nhlfe) == AF_INET6)
125 continue;
126
127 if (((action == RTM_ADD || action == RTM_CHANGE) &&
128 (CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_SELECTED) &&
129 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))) ||
130 (action == RTM_DELETE &&
131 (CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED) &&
132 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))))
133 {
134 nexthop_num++;
135
136 kernel_send_rtmsg (action, lsp->ile.in_label, nhlfe);
137 if (action == RTM_ADD || action == RTM_CHANGE)
138 {
139 SET_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED);
140 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
141 }
142 else
143 {
144 UNSET_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED);
145 UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
146 }
147 }
148 }
149
150 return (0);
151}
152
153int
154kernel_add_lsp (zebra_lsp_t *lsp)
155{
156 if (!lsp || !lsp->best_nhlfe) // unexpected
157 return -1;
158
159 return kernel_lsp_cmd (RTM_ADD, lsp);
160}
161
162int
163kernel_upd_lsp (zebra_lsp_t *lsp)
164{
165 if (!lsp || !lsp->best_nhlfe) // unexpected
166 return -1;
167
168 return kernel_lsp_cmd (RTM_CHANGE, lsp);
169}
170
171int
172kernel_del_lsp (zebra_lsp_t *lsp)
173{
174 if (!lsp) // unexpected
175 return -1;
176
177 return kernel_lsp_cmd (RTM_DELETE, lsp);
178}
179
180#define MAX_RTSOCK_BUF 128 * 1024
181void
182mpls_kernel_init (void)
183{
184 int rcvbuf, default_rcvbuf;
185 socklen_t optlen;
186
187 if ((kr_state.fd = socket(AF_ROUTE, SOCK_RAW, 0)) == -1) {
188 zlog_warn("kr_init: socket");
189 return;
190 }
191
192 /* grow receive buffer, don't wanna miss messages */
193 optlen = sizeof (default_rcvbuf);
194 if (getsockopt(kr_state.fd, SOL_SOCKET, SO_RCVBUF,
195 &default_rcvbuf, &optlen) == -1)
196 zlog_warn("kr_init getsockopt SOL_SOCKET SO_RCVBUF");
197 else
198 for (rcvbuf = MAX_RTSOCK_BUF;
199 rcvbuf > default_rcvbuf &&
200 setsockopt(kr_state.fd, SOL_SOCKET, SO_RCVBUF,
201 &rcvbuf, sizeof (rcvbuf)) == -1 && errno == ENOBUFS;
202 rcvbuf /= 2)
203 ; /* nothing */
204
205 kr_state.rtseq = 1;
206}