+ if (tb[RTA_SRC]) {
+ src.bitlen = r->rtm_src_len;
+ src.bytelen = (r->rtm_family == AF_INET6 ? 16 : 4);
+ memcpy(src.data, RTA_DATA(tb[RTA_SRC]), src.bytelen);
+ }
+ if (tb[RTA_DST]) {
+ dst.bitlen = r->rtm_dst_len;
+ dst.bytelen = (r->rtm_family == AF_INET6 ? 16 : 4);
+ memcpy(dst.data, RTA_DATA(tb[RTA_DST]), dst.bytelen);
+ }
+
+ if (G_filter.rdst.family
+ && inet_addr_match(&dst, &G_filter.rdst, G_filter.rdst.bitlen)
+ ) {
+ return 0;
+ }
+ if (G_filter.mdst.family
+ && G_filter.mdst.bitlen >= 0
+ && inet_addr_match(&dst, &G_filter.mdst, r->rtm_dst_len)
+ ) {
+ return 0;
+ }
+ if (G_filter.rsrc.family
+ && inet_addr_match(&src, &G_filter.rsrc, G_filter.rsrc.bitlen)
+ ) {
+ return 0;
+ }
+ if (G_filter.msrc.family && G_filter.msrc.bitlen >= 0
+ && inet_addr_match(&src, &G_filter.msrc, r->rtm_src_len)
+ ) {
+ return 0;
+ }
+ if (G_filter.oif != 0) {
+ if (!tb[RTA_OIF])
+ return 0;
+ if (G_filter.oif != *(int*)RTA_DATA(tb[RTA_OIF]))
+ return 0;
+ }
+
+ if (G_filter.flushb) {
+ struct nlmsghdr *fn;
+
+ /* We are creating route flush commands */
+
+ if (r->rtm_family == AF_INET6
+ && r->rtm_dst_len == 0
+ && r->rtm_type == RTN_UNREACHABLE
+ && tb[RTA_PRIORITY]
+ && *(int*)RTA_DATA(tb[RTA_PRIORITY]) == -1
+ ) {
+ return 0;
+ }
+
+ if (NLMSG_ALIGN(G_filter.flushp) + n->nlmsg_len > G_filter.flushe) {
+ if (flush_update())
+ bb_error_msg_and_die("flush");
+ }
+ fn = (void*)(G_filter.flushb + NLMSG_ALIGN(G_filter.flushp));
+ memcpy(fn, n, n->nlmsg_len);
+ fn->nlmsg_type = RTM_DELROUTE;
+ fn->nlmsg_flags = NLM_F_REQUEST;
+ fn->nlmsg_seq = ++G_filter.rth->seq;
+ G_filter.flushp = (((char*)fn) + n->nlmsg_len) - G_filter.flushb;
+ G_filter.flushed = 1;
+ return 0;
+ }
+
+ /* We are printing routes */
+