2 * OSPF network related functions
3 * Copyright (C) 1999 Toshiaki Takada
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
29 #include "sockunion.h"
34 extern struct zebra_privs_t ospfd_privs
;
36 #include "ospfd/ospfd.h"
37 #include "ospfd/ospf_network.h"
38 #include "ospfd/ospf_interface.h"
39 #include "ospfd/ospf_asbr.h"
40 #include "ospfd/ospf_lsa.h"
41 #include "ospfd/ospf_lsdb.h"
42 #include "ospfd/ospf_neighbor.h"
43 #include "ospfd/ospf_packet.h"
46 /* Join to the OSPF ALL SPF ROUTERS multicast group. */
47 int ospf_if_add_allspfrouters(struct ospf
*top
, struct prefix
*p
,
52 ret
= setsockopt_ipv4_multicast(top
->fd
, IP_ADD_MEMBERSHIP
,
53 p
->u
.prefix4
, htonl(OSPF_ALLSPFROUTERS
),
57 "can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, "
58 "ifindex %u, AllSPFRouters): %s; perhaps a kernel limit "
59 "on # of multicast group memberships has been exceeded?",
60 top
->fd
, inet_ntoa(p
->u
.prefix4
), ifindex
,
61 safe_strerror(errno
));
64 "interface %s [%u] join AllSPFRouters Multicast group.",
65 inet_ntoa(p
->u
.prefix4
), ifindex
);
70 int ospf_if_drop_allspfrouters(struct ospf
*top
, struct prefix
*p
,
75 ret
= setsockopt_ipv4_multicast(top
->fd
, IP_DROP_MEMBERSHIP
,
76 p
->u
.prefix4
, htonl(OSPF_ALLSPFROUTERS
),
80 "can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, "
81 "ifindex %u, AllSPFRouters): %s",
82 top
->fd
, inet_ntoa(p
->u
.prefix4
), ifindex
,
83 safe_strerror(errno
));
86 "interface %s [%u] leave AllSPFRouters Multicast group.",
87 inet_ntoa(p
->u
.prefix4
), ifindex
);
92 /* Join to the OSPF ALL Designated ROUTERS multicast group. */
93 int ospf_if_add_alldrouters(struct ospf
*top
, struct prefix
*p
,
98 ret
= setsockopt_ipv4_multicast(top
->fd
, IP_ADD_MEMBERSHIP
,
99 p
->u
.prefix4
, htonl(OSPF_ALLDROUTERS
),
103 "can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, "
104 "ifindex %u, AllDRouters): %s; perhaps a kernel limit "
105 "on # of multicast group memberships has been exceeded?",
106 top
->fd
, inet_ntoa(p
->u
.prefix4
), ifindex
,
107 safe_strerror(errno
));
110 "interface %s [%u] join AllDRouters Multicast group.",
111 inet_ntoa(p
->u
.prefix4
), ifindex
);
116 int ospf_if_drop_alldrouters(struct ospf
*top
, struct prefix
*p
,
121 ret
= setsockopt_ipv4_multicast(top
->fd
, IP_DROP_MEMBERSHIP
,
122 p
->u
.prefix4
, htonl(OSPF_ALLDROUTERS
),
126 "can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, "
127 "ifindex %u, AllDRouters): %s",
128 top
->fd
, inet_ntoa(p
->u
.prefix4
), ifindex
,
129 safe_strerror(errno
));
132 "interface %s [%u] leave AllDRouters Multicast group.",
133 inet_ntoa(p
->u
.prefix4
), ifindex
);
138 int ospf_if_ipmulticast(struct ospf
*top
, struct prefix
*p
, ifindex_t ifindex
)
143 /* Prevent receiving self-origined multicast packets. */
144 ret
= setsockopt_ipv4_multicast_loop(top
->fd
, 0);
146 zlog_warn("can't setsockopt IP_MULTICAST_LOOP(0) for fd %d: %s",
147 top
->fd
, safe_strerror(errno
));
149 /* Explicitly set multicast ttl to 1 -- endo. */
152 ret
= setsockopt(top
->fd
, IPPROTO_IP
, IP_MULTICAST_TTL
, (void *)&val
,
155 zlog_warn("can't setsockopt IP_MULTICAST_TTL(1) for fd %d: %s",
156 top
->fd
, safe_strerror(errno
));
158 ret
= setsockopt_ipv4_multicast_if(top
->fd
, p
->u
.prefix4
, ifindex
);
161 "can't setsockopt IP_MULTICAST_IF(fd %d, addr %s, "
163 top
->fd
, inet_ntoa(p
->u
.prefix4
), ifindex
,
164 safe_strerror(errno
));
169 int ospf_sock_init(void)
173 int bufsize
= (8 * 1024 * 1024);
175 if (ospfd_privs
.change(ZPRIVS_RAISE
))
176 zlog_err("ospf_sock_init: could not raise privs, %s",
177 safe_strerror(errno
));
179 ospf_sock
= socket(AF_INET
, SOCK_RAW
, IPPROTO_OSPFIGP
);
181 int save_errno
= errno
;
182 if (ospfd_privs
.change(ZPRIVS_LOWER
))
183 zlog_err("ospf_sock_init: could not lower privs, %s",
184 safe_strerror(errno
));
185 zlog_err("ospf_read_sock_init: socket: %s",
186 safe_strerror(save_errno
));
191 /* we will include IP header with packet */
192 ret
= setsockopt(ospf_sock
, IPPROTO_IP
, IP_HDRINCL
, &hincl
,
195 int save_errno
= errno
;
196 if (ospfd_privs
.change(ZPRIVS_LOWER
))
197 zlog_err("ospf_sock_init: could not lower privs, %s",
198 safe_strerror(errno
));
199 zlog_warn("Can't set IP_HDRINCL option for fd %d: %s",
200 ospf_sock
, safe_strerror(save_errno
));
202 #elif defined(IPTOS_PREC_INTERNETCONTROL)
203 #warning "IP_HDRINCL not available on this system"
204 #warning "using IPTOS_PREC_INTERNETCONTROL"
205 ret
= setsockopt_ipv4_tos(ospf_sock
, IPTOS_PREC_INTERNETCONTROL
);
207 int save_errno
= errno
;
208 if (ospfd_privs
.change(ZPRIVS_LOWER
))
209 zlog_err("ospf_sock_init: could not lower privs, %s",
210 safe_strerror(errno
));
211 zlog_warn("can't set sockopt IP_TOS %d to socket %d: %s", tos
,
212 ospf_sock
, safe_strerror(save_errno
));
213 close(ospf_sock
); /* Prevent sd leak. */
216 #else /* !IPTOS_PREC_INTERNETCONTROL */
217 #warning "IP_HDRINCL not available, nor is IPTOS_PREC_INTERNETCONTROL"
218 zlog_warn("IP_HDRINCL option not available");
219 #endif /* IP_HDRINCL */
221 ret
= setsockopt_ifindex(AF_INET
, ospf_sock
, 1);
224 zlog_warn("Can't set pktinfo option for fd %d", ospf_sock
);
226 if (ospfd_privs
.change(ZPRIVS_LOWER
)) {
227 zlog_err("ospf_sock_init: could not lower privs, %s",
228 safe_strerror(errno
));
231 setsockopt_so_sendbuf(ospf_sock
, bufsize
);
232 setsockopt_so_recvbuf(ospf_sock
, bufsize
);