#include "routemap.h"
#include "if_rmap.h"
#include "privs.h"
+#include "lib_errors.h"
#include "ripngd/ripngd.h"
#include "ripngd/ripng_route.h"
ripng_changed_route,
};
-extern struct zebra_privs_t ripngd_privs;
-
/* Prototypes. */
void ripng_output_process(struct interface *, struct sockaddr_in6 *, int);
sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (sock < 0) {
- zlog_err("Can't make ripng socket");
+ flog_err_sys(LIB_ERR_SOCKET, "Can't make ripng socket");
return sock;
}
setsockopt_so_recvbuf(sock, 8096);
ret = setsockopt_ipv6_pktinfo(sock, 1);
if (ret < 0)
- return ret;
+ goto error;
#ifdef IPTOS_PREC_INTERNETCONTROL
ret = setsockopt_ipv6_tclass(sock, IPTOS_PREC_INTERNETCONTROL);
if (ret < 0)
- return ret;
+ goto error;
#endif
ret = setsockopt_ipv6_multicast_hops(sock, 255);
if (ret < 0)
- return ret;
+ goto error;
ret = setsockopt_ipv6_multicast_loop(sock, 0);
if (ret < 0)
- return ret;
+ goto error;
ret = setsockopt_ipv6_hoplimit(sock, 1);
if (ret < 0)
- return ret;
+ goto error;
memset(&ripaddr, 0, sizeof(ripaddr));
ripaddr.sin6_family = AF_INET6;
#endif /* SIN6_LEN */
ripaddr.sin6_port = htons(RIPNG_PORT_DEFAULT);
- if (ripngd_privs.change(ZPRIVS_RAISE))
- zlog_err("ripng_make_socket: could not raise privs");
+ frr_elevate_privs(&ripngd_privs) {
- ret = bind(sock, (struct sockaddr *)&ripaddr, sizeof(ripaddr));
- if (ret < 0) {
- zlog_err("Can't bind ripng socket: %s.", safe_strerror(errno));
- if (ripngd_privs.change(ZPRIVS_LOWER))
- zlog_err("ripng_make_socket: could not lower privs");
- return ret;
+ ret = bind(sock, (struct sockaddr *)&ripaddr, sizeof(ripaddr));
+ if (ret < 0) {
+ zlog_err("Can't bind ripng socket: %s.", safe_strerror(errno));
+ goto error;
+ }
}
- if (ripngd_privs.change(ZPRIVS_LOWER))
- zlog_err("ripng_make_socket: could not lower privs");
return sock;
+
+error:
+ close(sock);
+ return ret;
}
/* Send RIPng packet. */
addr.sin6_port = htons(RIPNG_PORT_DEFAULT);
}
+ memset(&msg, 0, sizeof(msg));
msg.msg_name = (void *)&addr;
msg.msg_namelen = sizeof(struct sockaddr_in6);
msg.msg_iov = &iov;
if (ret < 0) {
if (to)
- zlog_err("RIPng send fail on %s to %s: %s", ifp->name,
- inet6_ntoa(to->sin6_addr),
- safe_strerror(errno));
+ flog_err_sys(LIB_ERR_SOCKET,
+ "RIPng send fail on %s to %s: %s",
+ ifp->name, inet6_ntoa(to->sin6_addr),
+ safe_strerror(errno));
else
- zlog_err("RIPng send fail on %s: %s", ifp->name,
- safe_strerror(errno));
+ flog_err_sys(LIB_ERR_SOCKET,
+ "RIPng send fail on %s: %s", ifp->name,
+ safe_strerror(errno));
}
return ret;
}
/* Receive UDP RIPng packet from socket. */
-static int ripng_recv_packet(int sock, u_char *buf, int bufsize,
+static int ripng_recv_packet(int sock, uint8_t *buf, int bufsize,
struct sockaddr_in6 *from, ifindex_t *ifindex,
int *hoplimit)
{
char adata[1024];
/* Fill in message and iovec. */
+ memset(&msg, 0, sizeof(msg));
msg.msg_name = (void *)from;
msg.msg_namelen = sizeof(struct sockaddr_in6);
msg.msg_iov = &iov;
/* Unlock route_node. */
listnode_delete(rp->info, rinfo);
if (list_isempty((struct list *)rp->info)) {
- list_free(rp->info);
- rp->info = NULL;
+ list_delete_and_null((struct list **)&rp->info);
route_unlock_node(rp);
}
unusable). */
if (rte->metric != RIPNG_METRIC_INFINITY)
ripng_ecmp_add(&newinfo);
+ else
+ route_unlock_node(rp);
} else {
/* If there is an existing route, compare the next hop address
to the address of the router from which the datagram came.
enabled interface. */
static int ripng_update(struct thread *t)
{
- struct listnode *node;
+ struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
struct interface *ifp;
struct ripng_interface *ri;
zlog_debug("RIPng update timer expired!");
/* Supply routes to each interface. */
- for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ FOR_ALL_INTERFACES (vrf, ifp) {
ri = ifp->info;
if (if_is_loopback(ifp) || !if_is_up(ifp))
/* Execute triggered update. */
int ripng_triggered_update(struct thread *t)
{
- struct listnode *node;
+ struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
struct interface *ifp;
struct ripng_interface *ri;
int interval;
/* Split Horizon processing is done when generating triggered
updates as well as normal updates (see section 2.6). */
- for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ FOR_ALL_INTERFACES (vrf, ifp) {
ri = ifp->info;
if (if_is_loopback(ifp) || !if_is_up(ifp))
/* Write routing table entry to the stream and return next index of
the routing table entry in the stream. */
int ripng_write_rte(int num, struct stream *s, struct prefix_ipv6 *p,
- struct in6_addr *nexthop, u_int16_t tag, u_char metric)
+ struct in6_addr *nexthop, uint16_t tag, uint8_t metric)
{
/* RIPng packet header. */
if (num == 0) {
}
/* Write routing table entry. */
- if (!nexthop)
- stream_write(s, (u_char *)&p->prefix, sizeof(struct in6_addr));
- else
- stream_write(s, (u_char *)nexthop, sizeof(struct in6_addr));
+ if (!nexthop) {
+ assert(p);
+ stream_write(s, (uint8_t *)&p->prefix, sizeof(struct in6_addr));
+ } else
+ stream_write(s, (uint8_t *)nexthop, sizeof(struct in6_addr));
stream_putw(s, tag);
if (p)
stream_putc(s, p->prefixlen);
len = 28 - len;
if (len > 0)
- len = vty_out(vty, "%*s", len, " ");
+ vty_out(vty, "%*s", len, " ");
/* from */
if ((rinfo->type == ZEBRA_ROUTE_RIPNG)
"Show RIPng routes\n"
"IPv6 routing protocol process parameters and statistics\n")
{
- struct listnode *node;
+ struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
struct interface *ifp;
if (!ripng)
vty_out(vty, " Interface Send Recv\n");
- for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
+ FOR_ALL_INTERFACES (vrf, ifp) {
struct ripng_interface *ri;
ri = ifp->info;
}
if (list_isempty(list)) {
- list_free(list);
+ list_delete_and_null(&list);
rp->info = NULL;
route_unlock_node(rp);
}
if (rp->info) {
vty_out(vty, "There is already same static route.\n");
route_unlock_node(rp);
- return CMD_WARNING_CONFIG_FAILED;
+ return CMD_WARNING;
}
rp->info = (void *)1;
if (node->info) {
vty_out(vty, "There is already same aggregate route.\n");
route_unlock_node(node);
- return CMD_WARNING_CONFIG_FAILED;
+ return CMD_WARNING;
}
node->info = (void *)1;
{
if (ripng->ecmp) {
vty_out(vty, "ECMP is already enabled.\n");
- return CMD_WARNING_CONFIG_FAILED;
+ return CMD_WARNING;
}
ripng->ecmp = 1;
{
if (!ripng->ecmp) {
vty_out(vty, "ECMP is already disabled.\n");
- return CMD_WARNING_CONFIG_FAILED;
+ return CMD_WARNING;
}
ripng->ecmp = 0;
/* Update all interface's distribute list. */
static void ripng_distribute_update_all(struct prefix_list *notused)
{
+ struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
struct interface *ifp;
- struct listnode *node;
- for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp))
+ FOR_ALL_INTERFACES (vrf, ifp)
ripng_distribute_update_interface(ifp);
}
rinfo->t_garbage_collect);
ripng_info_free(rinfo);
}
- list_delete(list);
+ list_delete_and_null(&list);
rp->info = NULL;
route_unlock_node(rp);
}
static void ripng_routemap_update(const char *unused)
{
+ struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
struct interface *ifp;
- struct listnode *node;
- for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp))
+ FOR_ALL_INTERFACES (vrf, ifp)
ripng_if_rmap_update_interface(ifp);
ripng_routemap_update_redistribute();