]> git.proxmox.com Git - mirror_frr.git/blame - ospfd/ospf_network.c
*: make consistent & update GPLv2 file headers
[mirror_frr.git] / ospfd / ospf_network.c
CommitLineData
718e3744 1/*
2 * OSPF network related functions
3 * Copyright (C) 1999 Toshiaki Takada
4 *
5 * This file is part of GNU Zebra.
6 *
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
10 * later version.
11 *
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.
16 *
896014f4
DL
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
718e3744 20 */
21
22#include <zebra.h>
23
24#include "thread.h"
25#include "linklist.h"
26#include "prefix.h"
27#include "if.h"
28#include "sockunion.h"
29#include "log.h"
30#include "sockopt.h"
edd7c245 31#include "privs.h"
32
33extern struct zebra_privs_t ospfd_privs;
718e3744 34
35#include "ospfd/ospfd.h"
36#include "ospfd/ospf_network.h"
37#include "ospfd/ospf_interface.h"
38#include "ospfd/ospf_asbr.h"
39#include "ospfd/ospf_lsa.h"
40#include "ospfd/ospf_lsdb.h"
41#include "ospfd/ospf_neighbor.h"
42#include "ospfd/ospf_packet.h"
43
edd7c245 44
45
718e3744 46/* Join to the OSPF ALL SPF ROUTERS multicast group. */
47int
48ospf_if_add_allspfrouters (struct ospf *top, struct prefix *p,
b892f1dd 49 ifindex_t ifindex)
718e3744 50{
51 int ret;
52
69bf3a39 53 ret = setsockopt_ipv4_multicast (top->fd, IP_ADD_MEMBERSHIP,
4a3867d0 54 p->u.prefix4, htonl (OSPF_ALLSPFROUTERS),
718e3744 55 ifindex);
56 if (ret < 0)
3dc56b5b 57 zlog_warn ("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, safe_strerror(errno));
718e3744 61 else
ec70497b 62 zlog_debug ("interface %s [%u] join AllSPFRouters Multicast group.",
42c98199 63 inet_ntoa (p->u.prefix4), ifindex);
718e3744 64
65 return ret;
66}
67
68int
69ospf_if_drop_allspfrouters (struct ospf *top, struct prefix *p,
b892f1dd 70 ifindex_t ifindex)
718e3744 71{
72 int ret;
73
69bf3a39 74 ret = setsockopt_ipv4_multicast (top->fd, IP_DROP_MEMBERSHIP,
4a3867d0 75 p->u.prefix4, htonl (OSPF_ALLSPFROUTERS),
718e3744 76 ifindex);
77 if (ret < 0)
3dc56b5b 78 zlog_warn ("can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, "
79 "ifindex %u, AllSPFRouters): %s",
80 top->fd, inet_ntoa(p->u.prefix4), ifindex, safe_strerror(errno));
718e3744 81 else
ec70497b
PJ
82 zlog_debug ("interface %s [%u] leave AllSPFRouters Multicast group.",
83 inet_ntoa (p->u.prefix4), ifindex);
718e3744 84
85 return ret;
86}
87
88/* Join to the OSPF ALL Designated ROUTERS multicast group. */
89int
b892f1dd 90ospf_if_add_alldrouters (struct ospf *top, struct prefix *p, ifindex_t ifindex)
718e3744 91{
92 int ret;
93
69bf3a39 94 ret = setsockopt_ipv4_multicast (top->fd, IP_ADD_MEMBERSHIP,
4a3867d0 95 p->u.prefix4, htonl (OSPF_ALLDROUTERS),
718e3744 96 ifindex);
97 if (ret < 0)
3dc56b5b 98 zlog_warn ("can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, "
99 "ifindex %u, AllDRouters): %s; perhaps a kernel limit "
100 "on # of multicast group memberships has been exceeded?",
101 top->fd, inet_ntoa(p->u.prefix4), ifindex, safe_strerror(errno));
718e3744 102 else
ec70497b
PJ
103 zlog_debug ("interface %s [%u] join AllDRouters Multicast group.",
104 inet_ntoa (p->u.prefix4), ifindex);
718e3744 105
106 return ret;
107}
108
109int
b892f1dd 110ospf_if_drop_alldrouters (struct ospf *top, struct prefix *p, ifindex_t ifindex)
718e3744 111{
112 int ret;
113
69bf3a39 114 ret = setsockopt_ipv4_multicast (top->fd, IP_DROP_MEMBERSHIP,
4a3867d0 115 p->u.prefix4, htonl (OSPF_ALLDROUTERS),
718e3744 116 ifindex);
117 if (ret < 0)
3dc56b5b 118 zlog_warn ("can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, "
119 "ifindex %u, AllDRouters): %s",
120 top->fd, inet_ntoa(p->u.prefix4), ifindex, safe_strerror(errno));
718e3744 121 else
ec70497b
PJ
122 zlog_debug ("interface %s [%u] leave AllDRouters Multicast group.",
123 inet_ntoa (p->u.prefix4), ifindex);
718e3744 124
125 return ret;
126}
127
128int
b892f1dd 129ospf_if_ipmulticast (struct ospf *top, struct prefix *p, ifindex_t ifindex)
718e3744 130{
131 u_char val;
132 int ret, len;
c5bdb09f 133
718e3744 134 /* Prevent receiving self-origined multicast packets. */
c5bdb09f 135 ret = setsockopt_ipv4_multicast_loop (top->fd, 0);
718e3744 136 if (ret < 0)
3dc56b5b 137 zlog_warn ("can't setsockopt IP_MULTICAST_LOOP(0) for fd %d: %s",
138 top->fd, safe_strerror(errno));
718e3744 139
140 /* Explicitly set multicast ttl to 1 -- endo. */
141 val = 1;
c5bdb09f 142 len = sizeof (val);
718e3744 143 ret = setsockopt (top->fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&val, len);
144 if (ret < 0)
3dc56b5b 145 zlog_warn ("can't setsockopt IP_MULTICAST_TTL(1) for fd %d: %s",
146 top->fd, safe_strerror (errno));
718e3744 147
4a3867d0 148 ret = setsockopt_ipv4_multicast_if (top->fd, p->u.prefix4, ifindex);
718e3744 149 if (ret < 0)
3dc56b5b 150 zlog_warn("can't setsockopt IP_MULTICAST_IF(fd %d, addr %s, "
151 "ifindex %u): %s",
152 top->fd, inet_ntoa(p->u.prefix4), ifindex, safe_strerror(errno));
718e3744 153
154 return ret;
155}
156
157int
158ospf_sock_init (void)
159{
160 int ospf_sock;
1423c809 161 int ret, hincl = 1;
a78d75b0 162 int bufsize = (8 * 1024 * 1024);
718e3744 163
edd7c245 164 if ( ospfd_privs.change (ZPRIVS_RAISE) )
165 zlog_err ("ospf_sock_init: could not raise privs, %s",
6099b3b5 166 safe_strerror (errno) );
edd7c245 167
718e3744 168 ospf_sock = socket (AF_INET, SOCK_RAW, IPPROTO_OSPFIGP);
169 if (ospf_sock < 0)
170 {
0b7d97d2 171 int save_errno = errno;
edd7c245 172 if ( ospfd_privs.change (ZPRIVS_LOWER) )
173 zlog_err ("ospf_sock_init: could not lower privs, %s",
6099b3b5 174 safe_strerror (errno) );
0b7d97d2 175 zlog_err ("ospf_read_sock_init: socket: %s", safe_strerror (save_errno));
176 exit(1);
718e3744 177 }
edd7c245 178
5bd4189c 179#ifdef IP_HDRINCL
180 /* we will include IP header with packet */
181 ret = setsockopt (ospf_sock, IPPROTO_IP, IP_HDRINCL, &hincl, sizeof (hincl));
182 if (ret < 0)
183 {
0b7d97d2 184 int save_errno = errno;
5bd4189c 185 if ( ospfd_privs.change (ZPRIVS_LOWER) )
186 zlog_err ("ospf_sock_init: could not lower privs, %s",
6099b3b5 187 safe_strerror (errno) );
0b7d97d2 188 zlog_warn ("Can't set IP_HDRINCL option for fd %d: %s",
189 ospf_sock, safe_strerror(save_errno));
5bd4189c 190 }
191#elif defined (IPTOS_PREC_INTERNETCONTROL)
192#warning "IP_HDRINCL not available on this system"
193#warning "using IPTOS_PREC_INTERNETCONTROL"
1423c809 194 ret = setsockopt_ipv4_tos(ospf_sock, IPTOS_PREC_INTERNETCONTROL);
718e3744 195 if (ret < 0)
196 {
0b7d97d2 197 int save_errno = errno;
edd7c245 198 if ( ospfd_privs.change (ZPRIVS_LOWER) )
199 zlog_err ("ospf_sock_init: could not lower privs, %s",
6099b3b5 200 safe_strerror (errno) );
0b7d97d2 201 zlog_warn ("can't set sockopt IP_TOS %d to socket %d: %s",
202 tos, ospf_sock, safe_strerror(save_errno));
718e3744 203 close (ospf_sock); /* Prevent sd leak. */
204 return ret;
205 }
5bd4189c 206#else /* !IPTOS_PREC_INTERNETCONTROL */
207#warning "IP_HDRINCL not available, nor is IPTOS_PREC_INTERNETCONTROL"
208 zlog_warn ("IP_HDRINCL option not available");
209#endif /* IP_HDRINCL */
718e3744 210
ac191232 211 ret = setsockopt_ifindex (AF_INET, ospf_sock, 1);
212
2dd8bb4e 213 if (ret < 0)
3dc56b5b 214 zlog_warn ("Can't set pktinfo option for fd %d", ospf_sock);
edd7c245 215
216 if (ospfd_privs.change (ZPRIVS_LOWER))
217 {
218 zlog_err ("ospf_sock_init: could not lower privs, %s",
6099b3b5 219 safe_strerror (errno) );
edd7c245 220 }
a78d75b0 221
6228a3b8
RW
222 setsockopt_so_sendbuf (ospf_sock, bufsize);
223 setsockopt_so_recvbuf (ospf_sock, bufsize);
a78d75b0 224
718e3744 225 return ospf_sock;
226}