diff options
Diffstat (limited to 'zebra')
-rw-r--r-- | zebra/debug.c | 4 | ||||
-rw-r--r-- | zebra/kernel_socket.h | 4 | ||||
-rw-r--r-- | zebra/rt_netlink.c | 50 | ||||
-rw-r--r-- | zebra/rtadv.h | 3 | ||||
-rw-r--r-- | zebra/zebra_rib.c | 153 |
5 files changed, 214 insertions, 0 deletions
diff --git a/zebra/debug.c b/zebra/debug.c index 175029b8..7350e576 100644 --- a/zebra/debug.c +++ b/zebra/debug.c @@ -236,7 +236,11 @@ DEFUN (no_debug_zebra_rib, DEFUN (no_debug_zebra_rib_q, no_debug_zebra_rib_q_cmd, +<<<<<<< HEAD:zebra/debug.c + "no debug zebra rib queueu", +======= "no debug zebra rib queue", +>>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/debug.c NO_STR DEBUG_STR "Zebra configuration\n" diff --git a/zebra/kernel_socket.h b/zebra/kernel_socket.h index e9558ad6..ad6770ca 100644 --- a/zebra/kernel_socket.h +++ b/zebra/kernel_socket.h @@ -28,6 +28,10 @@ extern int ifam_read (struct ifa_msghdr *); extern int ifm_read (struct if_msghdr *); extern int rtm_write (int, union sockunion *, union sockunion *, union sockunion *, unsigned int, int, int); +<<<<<<< HEAD:zebra/kernel_socket.h +extern struct message rtm_type_str[]; +======= extern const struct message rtm_type_str[]; +>>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/kernel_socket.h #endif /* __ZEBRA_KERNEL_SOCKET_H */ diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 05254498..07e86647 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -1831,12 +1831,57 @@ kernel_read (struct thread *thread) return 0; } +<<<<<<< HEAD:zebra/rt_netlink.c +/* Filter out messages from self that occur on listener socket */ +static void netlink_install_filter (int sock) +======= /* Filter out messages from self that occur on listener socket, caused by our actions on the command socket */ static void netlink_install_filter (int sock, __u32 pid) +>>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/rt_netlink.c { +<<<<<<< HEAD:zebra/rt_netlink.c + /* + * Filter is equivalent to netlink_route_change + * + * if (h->nlmsg_type == RTM_DELROUTE || h->nlmsg_type == RTM_NEWROUTE) { + * if (rtm->rtm_type != RTM_UNICAST) + * return 0; + * if (rtm->rtm_flags & RTM_F_CLONED) + * return 0; + * if (rtm->rtm_protocol == RTPROT_REDIRECT) + * return 0; + * if (rtm->rtm_protocol == RTPROT_KERNEL) + * return 0; + * if (rtm->rtm_protocol == RTPROT_ZEBRA && h->nlmsg_type == RTM_NEWROUTE) + * return 0; + * } + * return 0xffff; + */ +======= +>>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/rt_netlink.c struct sock_filter filter[] = { +<<<<<<< HEAD:zebra/rt_netlink.c + /* 0*/ BPF_STMT(BPF_LD|BPF_ABS|BPF_H, offsetof(struct nlmsghdr, nlmsg_type)), + /* 1*/ BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_DELROUTE), 1, 0), + /* 2*/ BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_NEWROUTE), 0, 11), + /* 3*/ BPF_STMT(BPF_LD|BPF_ABS|BPF_B, + sizeof(struct nlmsghdr) + offsetof(struct rtmsg, rtm_type)), + /* 4*/ BPF_JUMP(BPF_JMP|BPF_B, RTN_UNICAST, 0, 8), + /* 5*/ BPF_STMT(BPF_LD|BPF_ABS|BPF_B, + sizeof(struct nlmsghdr) + offsetof(struct rtmsg, rtm_flags)), + /* 6*/ BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, RTM_F_CLONED, 6, 0), + /* 7*/ BPF_STMT(BPF_LD|BPF_ABS|BPF_B, + sizeof(struct nlmsghdr) + offsetof(struct rtmsg, rtm_protocol)), + /* 8*/ BPF_JUMP(BPF_JMP+ BPF_B, RTPROT_REDIRECT, 4, 0), + /* 9*/ BPF_JUMP(BPF_JMP+ BPF_B, RTPROT_KERNEL, 0, 1), + /*10*/ BPF_JUMP(BPF_JMP+ BPF_B, RTPROT_ZEBRA, 0, 3), + /*11*/ BPF_STMT(BPF_LD|BPF_ABS|BPF_H, offsetof(struct nlmsghdr, nlmsg_type)), + /*12*/ BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_NEWROUTE), 0, 1), + /*13*/ BPF_STMT(BPF_RET|BPF_K, 0), /* drop */ + /*14*/ BPF_STMT(BPF_RET|BPF_K, 0xffff), /* keep */ +======= /* 0: ldh [4] */ BPF_STMT(BPF_LD|BPF_ABS|BPF_H, offsetof(struct nlmsghdr, nlmsg_type)), /* 1: jeq 0x18 jt 3 jf 6 */ @@ -1851,6 +1896,7 @@ static void netlink_install_filter (int sock, __u32 pid) BPF_STMT(BPF_RET|BPF_K, 0), /* 6: ret 0xffff (keep) */ BPF_STMT(BPF_RET|BPF_K, 0xffff), +>>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/rt_netlink.c }; struct sock_fprog prog = { @@ -1879,6 +1925,9 @@ kernel_init (void) /* Register kernel socket. */ if (netlink.sock > 0) { +<<<<<<< HEAD:zebra/rt_netlink.c + netlink_install_filter (netlink.sock); +======= /* Only want non-blocking on the netlink event socket */ if (fcntl (netlink.sock, F_SETFL, O_NONBLOCK) < 0) zlog (NULL, LOG_ERR, "Can't set %s socket flags: %s", netlink.name, @@ -1889,6 +1938,7 @@ kernel_init (void) netlink_recvbuf (&netlink, nl_rcvbufsize); netlink_install_filter (netlink.sock, netlink_cmd.snl.nl_pid); +>>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/rt_netlink.c thread_add_read (zebrad.master, kernel_read, NULL, netlink.sock); } } diff --git a/zebra/rtadv.h b/zebra/rtadv.h index abd1c6fc..658bc5ff 100644 --- a/zebra/rtadv.h +++ b/zebra/rtadv.h @@ -23,7 +23,10 @@ #ifndef _ZEBRA_RTADV_H #define _ZEBRA_RTADV_H +<<<<<<< HEAD:zebra/rtadv.h +======= #include "vty.h" +>>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/rtadv.h #include "zebra/interface.h" /* Router advertisement prefix. */ diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 90db932b..1cb9856a 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -683,12 +683,21 @@ rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate) /* Find out if a "selected" RR for the discovered RIB entry exists ever. */ for (match = rn->info; match; match = match->next) +<<<<<<< HEAD:zebra/zebra_rib.c + { + if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED)) + continue; + if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED)) + break; + } +======= { if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED)) continue; if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED)) break; } +>>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/zebra_rib.c /* None such found :( */ if (!match) @@ -1191,6 +1200,7 @@ rib_process (struct route_node *rn) rn->p.prefixlen, del, rn); rib_unlink (rn, del); } +<<<<<<< HEAD:zebra/zebra_rib.c end: if (IS_ZEBRA_DEBUG_RIB_Q) @@ -1201,6 +1211,107 @@ end: * it and processed by rib_process(). Don't process more, than one RN record; operate * only in the specified sub-queue. */ +unsigned int +process_subq (struct list * subq, u_char qindex) +{ + struct listnode *lnode; + struct route_node *rnode; + if (!(lnode = listhead (subq))) + return 0; + rnode = listgetdata (lnode); + rib_process (rnode); + if (rnode->info) /* The first RIB record is holding the flags bitmask. */ + UNSET_FLAG (((struct rib *)rnode->info)->rn_status, RIB_ROUTE_QUEUED(qindex)); + route_unlock_node (rnode); + list_delete_node (subq, lnode); + return 1; +} + +/* Dispatch the meta queue by picking, processing and unlocking the next RN from + * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data + * is pointed to the meta queue structure. + */ +static wq_item_status +meta_queue_process (struct work_queue *dummy, void *data) +{ + struct meta_queue * mq = data; + u_char i; + for (i = 0; i < MQ_SIZE; i++) + if (process_subq (mq->subq[i], i)) + { + mq->size--; + break; + } + return mq->size ? WQ_REQUEUE : WQ_SUCCESS; +} +======= +>>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/zebra_rib.c + +<<<<<<< HEAD:zebra/zebra_rib.c +/* Look into the RN and queue it into one or more priority queues, increasing the size + * for each data push done. + */ +void rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn) +{ + u_char qindex; + struct rib *rib; + char buf[INET6_ADDRSTRLEN]; +======= +end: +>>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/zebra_rib.c + if (IS_ZEBRA_DEBUG_RIB_Q) +<<<<<<< HEAD:zebra/zebra_rib.c + inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); + for (rib = rn->info; rib; rib = rib->next) + { + switch (rib->type) + { + case ZEBRA_ROUTE_KERNEL: + case ZEBRA_ROUTE_CONNECT: + qindex = 0; + break; + case ZEBRA_ROUTE_STATIC: + qindex = 1; + break; + case ZEBRA_ROUTE_RIP: + case ZEBRA_ROUTE_RIPNG: + case ZEBRA_ROUTE_OSPF: + case ZEBRA_ROUTE_OSPF6: + case ZEBRA_ROUTE_ISIS: + qindex = 2; + break; + case ZEBRA_ROUTE_BGP: + qindex = 3; + break; + default: + qindex = 4; + break; + } + /* Invariant: at this point we always have rn->info set. */ + if (CHECK_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex))) + { + if (IS_ZEBRA_DEBUG_RIB_Q) + zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u", __func__, buf, rn->p.prefixlen, rn, qindex); + continue; + } + SET_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex)); + listnode_add (mq->subq[qindex], rn); + route_lock_node (rn); + mq->size++; + if (IS_ZEBRA_DEBUG_RIB_Q) + zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u", __func__, buf, rn->p.prefixlen, rn, qindex); + } +======= + zlog_debug ("%s: %s/%d: rn %p dequeued", __func__, buf, rn->p.prefixlen, rn); +>>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/zebra_rib.c +} + +<<<<<<< HEAD:zebra/zebra_rib.c +======= +/* Take a list of route_node structs and return 1, if there was a record picked from + * it and processed by rib_process(). Don't process more, than one RN record; operate + * only in the specified sub-queue. + */ static unsigned int process_subq (struct list * subq, u_char qindex) { @@ -1287,6 +1398,7 @@ rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn) } } +>>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/zebra_rib.c /* Add route_node to work queue and schedule processing */ static void rib_queue_add (struct zebra_t *zebra, struct route_node *rn) @@ -1329,16 +1441,30 @@ rib_queue_add (struct zebra_t *zebra, struct route_node *rn) work_queue_add (zebra->ribq, zebra->mq); rib_meta_queue_add (zebra->mq, rn); +<<<<<<< HEAD:zebra/zebra_rib.c +======= + + if (IS_ZEBRA_DEBUG_RIB_Q) + zlog_debug ("%s: %s/%d: rn %p queued", __func__, buf, rn->p.prefixlen, rn); +>>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/zebra_rib.c +<<<<<<< HEAD:zebra/zebra_rib.c if (IS_ZEBRA_DEBUG_RIB_Q) zlog_debug ("%s: %s/%d: rn %p queued", __func__, buf, rn->p.prefixlen, rn); +======= +>>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/zebra_rib.c return; } /* Create new meta queue. A destructor function doesn't seem to be necessary here. */ +<<<<<<< HEAD:zebra/zebra_rib.c +struct meta_queue * +meta_queue_new () +======= static struct meta_queue * meta_queue_new (void) +>>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/zebra_rib.c { struct meta_queue *new; unsigned i, failed = 0; @@ -1461,7 +1587,32 @@ rib_link (struct route_node *rn, struct rib *rib) static void rib_addnode (struct route_node *rn, struct rib *rib) +<<<<<<< HEAD:zebra/zebra_rib.c +======= +{ + /* RIB node has been un-removed before route-node is processed. + * route_node must hence already be on the queue for processing.. + */ + if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) + { + if (IS_ZEBRA_DEBUG_RIB) + { + char buf[INET6_ADDRSTRLEN]; + inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN); + zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p", + __func__, buf, rn->p.prefixlen, rn, rib); + } + UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED); + return; + } + rib_link (rn, rib); +} + +static void +rib_unlink (struct route_node *rn, struct rib *rib) +>>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/zebra_rib.c { +<<<<<<< HEAD:zebra/zebra_rib.c /* RIB node has been un-removed before route-node is processed. * route_node must hence already be on the queue for processing.. */ @@ -1483,6 +1634,8 @@ rib_addnode (struct route_node *rn, struct rib *rib) static void rib_unlink (struct route_node *rn, struct rib *rib) { +======= +>>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/zebra_rib.c struct nexthop *nexthop, *next; char buf[INET6_ADDRSTRLEN]; |