]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Merge branch 'master' into int-new
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 8 Nov 2016 18:27:58 +0000 (19:27 +0100)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 8 Nov 2016 18:27:58 +0000 (19:27 +0100)
51 files changed:
1  2 
conf/Makefile
conf/cf-lex.l
conf/conf.c
conf/conf.h
conf/confbase.Y
configure.in
doc/Makefile
filter/config.Y
filter/filter.c
filter/filter.h
filter/test.conf
filter/trie.c
lib/Makefile
lib/birdlib.h
lib/hash.h
lib/idm.c
lib/socket.h
nest/config.Y
nest/password.h
nest/route.h
nest/rt-attr.c
nest/rt-table.c
proto/bfd/bfd.c
proto/bfd/bfd.h
proto/bfd/packets.c
proto/bgp/bgp.c
proto/bgp/config.Y
proto/ospf/config.Y
proto/ospf/hello.c
proto/ospf/iface.c
proto/ospf/lsalib.c
proto/ospf/ospf.h
proto/ospf/packet.c
proto/ospf/rt.c
proto/ospf/topology.c
proto/pipe/pipe.c
proto/radv/packets.c
proto/radv/radv.c
proto/rip/config.Y
proto/rip/packets.c
proto/rip/rip.c
proto/rip/rip.h
proto/static/static.c
sysdep/bsd/krt-sock.c
sysdep/bsd/krt-sys.h
sysdep/bsd/sysio.h
sysdep/linux/netlink.c
sysdep/unix/io.c
sysdep/unix/krt.c
sysdep/unix/log.c
sysdep/unix/main.c

diff --cc conf/Makefile
index c1a906e3e77ba5f1766e30f77a65115621427c4a,cd78c82128775251388d2cab1a5988968588f161..e5828538d58719512e85590f8c58fd035373bd1d
@@@ -8,23 -11,23 +8,24 @@@ BISON_DEBUG=-
  #FLEX_DEBUG=-d
  endif
  
 -cf-parse.tab.h: cf-parse.tab.c
 +$(conf-y-targets): $(s)confbase.Y
 +      $(M4) -P $| $^ >$@
  
 -cf-parse.tab.c: cf-parse.y
 -      $(BISON) -bcf-parse -dv -pcf_ $(BISON_DEBUG) cf-parse.y
 +$(o)cf-parse.y: | $(s)gen_parser.m4
 +$(o)keywords.h: | $(s)gen_keywords.m4
 +$(o)commands.h: | $(s)gen_commands.m4 $(srcdir)/client/cmds.m4
  
 -cf-parse.y: $(conf-fragments) $(conf-src)/gen_parser.m4
 -      $(M4) -P $(conf-src)/gen_parser.m4 $(conf-fragments) >cf-parse.y
 +$(o)cf-parse.tab.h: $(o)cf-parse.tab.c
  
 -keywords.h: $(conf-fragments) $(conf-src)/gen_keywords.m4
 -      $(M4) -P $(conf-src)/gen_keywords.m4 $(conf-fragments) >keywords.h
 +$(o)cf-parse.tab.c: $(o)cf-parse.y
 +      $(BISON) $(BISON_DEBUG) -dv -pcf_ -b $(@:.tab.c=) $<
  
 -commands.h: $(conf-fragments) $(conf-src)/gen_commands.m4 $(srcdir)/client/cmds.m4
 -      $(M4) -P $(conf-src)/gen_commands.m4 $(srcdir)/client/cmds.m4 $(conf-fragments) | sort >commands.h
 +$(o)cf-lex.c: $(s)cf-lex.l
 +      $(FLEX) $(FLEX_DEBUG) -s -B -8 -Pcf_ -o$@ $<
  
 -cf-lex.c: cf-lex.l
 -      $(FLEX) $(FLEX_DEBUG) -s -B -8 -ocf-lex.c -Pcf_ cf-lex.l
 +$(o)cf-lex.o: $(o)cf-parse.tab.h $(o)keywords.h
++$(o)cf-lex.o: CFLAGS+=-Wno-sign-compare -Wno-unused-function
  
 -depend: keywords.h commands.h cf-parse.tab.c cf-lex.c
 +$(addprefix $(o), cf-parse.y keywords.h commands.h cf-parse.tab.h cf-parse.tab.c cf-lex.c): $(objdir)/.dir-stamp
  
 -cf-lex.o: CFLAGS+=-Wno-sign-compare -Wno-unused-function
 +$(call clean,cf-parse.tab.h cf-parse.tab.c cf-parse.y keywords.h commands.h cf-lex.c cf-parse.output)
diff --cc conf/cf-lex.l
Simple merge
diff --cc conf/conf.c
Simple merge
diff --cc conf/conf.h
index 03fecd32a024ad7900bd05443ebba065ff58e718,41cb434fd6b68a89ecfaeee9aec528c54190f341..593a5f1326cbad38564ba6ef62056e2ac8118332
@@@ -20,7 -20,8 +20,7 @@@ struct config 
    linpool *mem;                               /* Linear pool containing configuration data */
    list protos;                                /* Configured protocol instances (struct proto_config) */
    list tables;                                /* Configured routing tables (struct rtable_config) */
-   list logfiles;                      /* Configured log fils (sysdep) */
 -  list roa_tables;                    /* Configured ROA tables (struct roa_table_config) */
+   list logfiles;                      /* Configured log files (sysdep) */
  
    int mrtdump_file;                   /* Configured MRTDump file (sysdep, fd in unix) */
    char *syslog_name;                  /* Name used for syslog (NULL -> no syslog) */
diff --cc conf/confbase.Y
index 22edbdfdb61b812cfdd525933261022a410215aa,96b32028cc1c791dc3f35901383819e69d5e55fa..094c81b55cf3b3b04485262e3e3b27ed124d0c3f
@@@ -182,88 -168,19 +182,88 @@@ pxlen4
     }
   ;
  
 -prefix_or_ipa:
 -   prefix
 - | ipa { $$.addr = $1; $$.len = BITS_PER_IP_ADDRESS; }
 +net_ip4_: IP4 pxlen4
 +{
 +  net_fill_ip4(&($$), $1, $2);
 +  if (!net_validate_ip4((net_addr_ip4 *) &($$)))
 +    cf_error("Invalid IPv4 prefix");
 +};
 +
 +net_ip6_: IP6 '/' NUM
 +{
 +  net_fill_ip6(&($$), $1, $3);
 +  if ($3 < 0 || $3 > IP6_MAX_PREFIX_LENGTH)
 +    cf_error("Invalid prefix length %d", $3);
 +  if (!net_validate_ip6((net_addr_ip6 *) &($$)))
 +    cf_error("Invalid IPv6 prefix");
 +};
 +
 +net_roa4_: net_ip4_ MAX NUM AS NUM
 +{
 +  $$ = cfg_alloc(sizeof(net_addr_roa4));
 +  net_fill_roa4($$, net4_prefix(&$1), net4_pxlen(&$1), $3, $5);
-   if ($3 < net4_pxlen(&$1) || $3 > IP4_MAX_PREFIX_LENGTH)
++  if ($3 < (int) net4_pxlen(&$1) || $3 > IP4_MAX_PREFIX_LENGTH)
 +    cf_error("Invalid max prefix length %d", $3);
 +};
 +
 +net_roa6_: net_ip6_ MAX NUM AS NUM
 +{
 +  $$ = cfg_alloc(sizeof(net_addr_roa6));
 +  net_fill_roa6($$, net6_prefix(&$1), net6_pxlen(&$1), $3, $5);
-   if ($3 < net6_pxlen(&$1) || $3 > IP6_MAX_PREFIX_LENGTH)
++  if ($3 < (int) net6_pxlen(&$1) || $3 > IP6_MAX_PREFIX_LENGTH)
 +    cf_error("Invalid max prefix length %d", $3);
 +};
 +
 +net_ip_: net_ip4_ | net_ip6_ ;
 +net_roa_: net_roa4_ | net_roa6_ ;
 +
 +net_:
 +   net_ip_ { $$ = cfg_alloc($1.length); net_copy($$, &($1)); }
 + | net_roa_
   ;
  
 -pxlen:
 -   '/' expr {
 -     if ($2 < 0 || $2 > BITS_PER_IP_ADDRESS) cf_error("Invalid prefix length %d", $2);
 -     $$ = $2;
 +
 +/* Networks - regular */
 +
 +net_ip6:
 +   net_ip6_
 + | SYM {
 +     if (($1->class != (SYM_CONSTANT | T_NET)) || (SYM_VAL($1).net->type != NET_IP6))
 +       cf_error("IPv6 network expected");
 +     $$ = * SYM_VAL($1).net;
 +   }
 + ;
 +
 +net_ip:
 +   net_ip_
 + | SYM {
 +     if (($1->class != (SYM_CONSTANT | T_NET)) || !net_is_ip(SYM_VAL($1).net))
 +       cf_error("IP network expected");
 +     $$ = * SYM_VAL($1).net;
 +   }
 + ;
 +
 +net_any:
 +   net_
 + | SYM {
 +     if ($1->class != (SYM_CONSTANT | T_NET))
 +       cf_error("Network expected");
 +     $$ = (net_addr *) SYM_VAL($1).net; /* Avoid const warning */
     }
 - | ':' ipa {
 -     $$ = ipa_masklen($2);
 -     if ($$ < 0) cf_error("Invalid netmask %I", $2);
 + ;
 +
 +net_or_ipa:
 +   net_ip4_
 + | net_ip6_
 + | IP4 { net_fill_ip4(&($$), $1, IP4_MAX_PREFIX_LENGTH); }
 + | IP6 { net_fill_ip6(&($$), $1, IP6_MAX_PREFIX_LENGTH); }
 + | SYM {
 +     if ($1->class == (SYM_CONSTANT | T_IP))
 +       net_fill_ip_host(&($$), SYM_VAL($1).ip);
 +     else if (($1->class == (SYM_CONSTANT | T_NET)) && net_is_ip(SYM_VAL($1).net))
 +       $$ = * SYM_VAL($1).net;
 +     else
 +       cf_error("IP address or network expected");
     }
   ;
  
diff --cc configure.in
Simple merge
diff --cc doc/Makefile
index 3ff733894728e63763fbc1b286c9893e21d548d5,70b73943f300b158bc6ac570a57cc198fd5e8812..4e7e91ebf2e9a7dcf219bdce1a6ab9b268677bed
@@@ -1,48 -1,50 +1,49 @@@
 -root-rel=../
 -dir-name=doc
 -
 -ifneq ($(wildcard ../Rules),)
 -include ../Rules
 -else
 -srcdir=$(shell cd $(root-rel) ; pwd)
 -srcdir_abs=$(srcdir)
 -endif
 -
  # Force rebuilds
 -.PHONY: prog.sgml bird.sgml
 +.PHONY: progspell docs progdocs userdocs
 +
 +doc-srcdir := $(shell cd $(s) && pwd)
 +sgml2 := $(doc-srcdir)/sgml2
  
  docs: progdocs userdocs
 -progdocs: prog.html prog.ps
 -userdocs: bird.html bird.pdf
  
 -prog.sgml:
 -      $(srcdir)/tools/progdoc $(srcdir_abs)
 +doc-fmt = $(1): $(o)prog.$(1) $(o)bird.$(1)
 +$(call doc-fmt,html)
 +$(call doc-fmt,dvi)
 +$(call doc-fmt,ps)
 +$(call doc-fmt,pdf)
  
 -%.html: %.sgml
 -      ./sgml2html $<
 +progdocs: $(o)prog.html $(o)prog.pdf
 +userdocs: $(o)bird.html $(o)bird.pdf
 +progspell: $(o)prog.spell
  
 -%.dvi: %.tex
 -      latex $<
 -      latex $<
 +$(o)prog.sgml: $(srcdir)/tools/progdoc $(objdir)/.dir-stamp
 +      $(srcdir)/tools/progdoc $(srcdir) $@
  
 -%.ps: %.dvi
 -      dvips -D600 -ta4 -o $@ $<
 +$(o)%.sgml: $(s)%.sgml $(objdir)/.dir-stamp
 +      cp $< $@
  
 -%.pdf: %.tex
 -      pdflatex $<
 -      pdflatex $<
 +$(o)%.html: $(o)%.sgml
 +      cd $(dir $@) && $(sgml2)html $(notdir $<)
  
 -%.tex: %.sgml
 -      ./sgml2latex --output=tex $<
++$(o)%.tex: $(o)%.sgml
++      cd $(dir $@) && $(sgml2)latex --output=tex $(notdir $<)
++
 +$(o)%.dvi: $(o)%.tex
 +      cd $(dir $@) && TEXINPUTS=$(TEXINPUTS):$(doc-srcdir)/tex latex $(notdir $<)
 +      cd $(dir $@) && TEXINPUTS=$(TEXINPUTS):$(doc-srcdir)/tex latex $(notdir $<)
 +
 +$(o)%.ps: $(o)%.dvi
 +      dvips -D600 -ta4 -o $@ $<
  
- $(o)%.pdf: $(o)%.ps
-       ps2pdf $< $@
- $(o)%.tex: $(o)%.sgml
-       cd $(dir $@) && $(sgml2)latex --output=tex $(notdir $<)
 -%.txt: %.sgml
 -      ./sgml2txt $<
++$(o)%.pdf: $(o)%.tex
++      pdflatex -output-directory=$(dir $@) $<
++      pdflatex -output-directory=$(dir $@) $<
  
 -progspell: prog.sgml
 -      sed -f prog-spell.sed <prog.sgml >prog.spell
 -      ispell prog.spell
 +$(o)%.txt: $(o)%.sgml
 +      cd $(dir $@) && $(sgml2)txt $(notdir $<)
  
 -clean:
 -      rm -f *.tex *.dvi *.log *.txt *.aux *.toc *.spell
 -      rm -f prog.sgml
 +$(o)prog.spell: $(o)prog.sgml $(s)prog-spell.sed
 +      sed -f $(lastword $^) <$< >$@
 +      ispell $@
  
 -distclean: clean
 -      rm -f *.html *.ps
 +$(call clean,prog.spell $(addprefix *.,html dvi ps pdf sgml tex txt aux log toc))
diff --cc filter/config.Y
index 3eb5b08f29f56ce94a2adce5ef9c99bc18c8d8a6,5ea83f81b21ca55b4fd7b1b2fd405c4cb1c5a335..8af444a3b36a1609f3a20dc079e5a2003edbcf84
@@@ -291,12 -350,11 +348,12 @@@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UN
  
  %type <x> term block cmds cmds_int cmd function_body constant constructor print_one print_list var_list var_listn dynamic_attr static_attr function_call symbol bgp_path_expr
  %type <f> filter filter_body where_filter
- %type <i> type break_command pair_expr ec_kind
- %type <i32> pair_atom ec_expr
- %type <e> pair_item ec_item set_item switch_item set_items switch_items switch_body
+ %type <i> type break_command ec_kind
+ %type <i32> cnum
+ %type <e> pair_item ec_item lc_item set_item switch_item set_items switch_items switch_body
  %type <trie> fprefix_set
 -%type <v> set_atom switch_atom fprefix fprefix_s fipa
 +%type <v> set_atom switch_atom fipa
 +%type <px> fprefix
  %type <s> decls declsn one_decl function_params
  %type <h> bgp_path bgp_path_tail1 bgp_path_tail2
  
diff --cc filter/filter.c
index 3282bd50f91999461bb768a7b4058727de0dc725,85a0625860896637bd6f926aa20dd19e00d854f2..09b89401a2b6461e369f9a8b8e686af3dc2e9f8d
@@@ -96,9 -94,30 +96,21 @@@ pm_format(struct f_path_mask *p, buffe
    buffer_puts(buf, "=]");
  }
  
 -static inline int
 -uint_cmp(uint i1, uint i2)
 -{
 -  return (int)(i1 > i2) - (int)(i1 < i2);
 -}
 -
 -static inline int
 -u64_cmp(u64 i1, u64 i2)
 -{
 -  return (int)(i1 > i2) - (int)(i1 < i2);
 -}
 +static inline int val_is_ip4(const struct f_val v)
 +{ return (v.type == T_IP) && ipa_is_ip4(v.val.ip); }
  
+ static inline int
+ lcomm_cmp(lcomm v1, lcomm v2)
+ {
+   if (v1.asn != v2.asn)
+     return (v1.asn > v2.asn) ? 1 : -1;
+   if (v1.ldp1 != v2.ldp1)
+     return (v1.ldp1 > v2.ldp1) ? 1 : -1;
+   if (v1.ldp2 != v2.ldp2)
+     return (v1.ldp2 > v2.ldp2) ? 1 : -1;
+   return 0;
+ }
  /**
   * val_compare - compare two values
   * @v1: first value
@@@ -138,10 -161,14 +150,12 @@@ val_compare(struct f_val v1, struct f_v
      return uint_cmp(v1.val.i, v2.val.i);
    case T_EC:
      return u64_cmp(v1.val.ec, v2.val.ec);
+   case T_LC:
+     return lcomm_cmp(v1.val.lc, v2.val.lc);
    case T_IP:
 -    return ipa_compare(v1.val.px.ip, v2.val.px.ip);
 -  case T_PREFIX:
 -    if (rc = ipa_compare(v1.val.px.ip, v2.val.px.ip))
 -      return rc;
 -    return uint_cmp(v1.val.px.len, v2.val.px.len);
 +    return ipa_compare(v1.val.ip, v2.val.ip);
 +  case T_NET:
 +    return net_compare(v1.val.net, v2.val.net);
    case T_STRING:
      return strcmp(v1.val.s, v2.val.s);
    default:
diff --cc filter/filter.h
index af4901210b6f6e11ef83a39df8fb1d6837dd8d23,049ceb767a23f14ed0bb594695f6001a02e1cd9e..fc11b91eb8cbf7abb5a432df8bc51201ab2da755
@@@ -35,12 -35,28 +35,23 @@@ struct f_inst {            /* Instruction *
  /* Not enough fields in f_inst for three args used by roa_check() */
  struct f_inst_roa_check {
    struct f_inst i;
 -  struct roa_table_config *rtc;
 +  struct rtable_config *rtc;
  };
  
+ struct f_inst3 {
+   struct f_inst i;
+   union {
+     int i;
+     void *p;
+   } a3;
+ };
+ #define INST3(x) (((struct f_inst3 *) x)->a3)
  struct f_prefix {
 -  ip_addr ip;
 -  int len;
 -#define LEN_MASK 0xff
 -#define LEN_PLUS  0x1000000
 -#define LEN_MINUS 0x2000000
 -#define LEN_RANGE 0x4000000
 -  /* If range then prefix must be in range (len >> 16 & 0xff, len >> 8 & 0xff) */
 +  net_addr net;
 +  u8 lo, hi;
  };
  
  struct f_val {
@@@ -48,8 -64,9 +59,9 @@@
    union {
      uint i;
      u64 ec;
 -    /*    ip_addr ip; Folded into prefix */
 -    struct f_prefix px;
+     lcomm lc;
 +    ip_addr ip;
 +    const net_addr *net;
      char *s;
      struct f_tree *t;
      struct f_trie *ti;
@@@ -175,7 -211,7 +189,7 @@@ struct f_tree 
  struct f_trie_node
  {
    ip_addr addr, mask, accept;
--  int plen;
++  uint plen;
    struct f_trie_node *c[2];
  };
  
Simple merge
diff --cc filter/trie.c
index dad873397dfeb3703460224a289bc9ba02cff56c,565ae82f6b27beb40cf7644f3fa73c43317e4caf..adcfcdf3f031fea798db44985429d9f8be0bdead
@@@ -219,8 -196,18 +219,8 @@@ trie_add_prefix(struct f_trie *t, cons
    return a;
  }
  
 -/**
 - * trie_match_prefix
 - * @t: trie
 - * @px: prefix address
 - * @plen: prefix length
 - *
 - * Tries to find a matching prefix pattern in the trie such that
 - * prefix @px/@plen matches that prefix pattern. Returns 1 if there
 - * is such prefix pattern in the trie.
 - */
 -int
 -trie_match_prefix(struct f_trie *t, ip_addr px, int plen)
 +static int
- trie_match_prefix(struct f_trie *t, ip_addr px, int plen)
++trie_match_prefix(struct f_trie *t, ip_addr px, uint plen)
  {
    ip_addr pmask = ipa_mkmask(plen);
    ip_addr paddr = ipa_and(px, pmask);
    return 0;
  }
  
-   int add = 0;
 +/**
 + * trie_match_net
 + * @t: trie
 + * @n: net address
 + *
 + * Tries to find a matching net in the trie such that
 + * prefix @n matches that prefix pattern. Returns 1 if there
 + * is such prefix pattern in the trie.
 + */
 +int
 +trie_match_net(struct f_trie *t, const net_addr *n)
 +{
++  uint add = 0;
++
 +  switch (n->type) {
 +    case NET_IP4:
 +    case NET_VPN4:
 +    case NET_ROA4:
 +      add = IP6_MAX_PREFIX_LENGTH - IP4_MAX_PREFIX_LENGTH;
 +  }
 +
 +  return trie_match_prefix(t, net_prefix(n), net_pxlen(n) + add);
 +}
 +
  static int
  trie_node_same(struct f_trie_node *t1, struct f_trie_node *t2)
  {
diff --cc lib/Makefile
index 8e372bd31f4c5ba82c3387128ddb746d13676d77,0000000000000000000000000000000000000000..551089c3bc60a8fa723c37e8c2eb87d70017ecb1
mode 100644,000000..100644
--- /dev/null
@@@ -1,3 -1,0 +1,3 @@@
- src := bitops.c checksum.c event.c idm.c ip.c lists.c md5.c mempool.c net.c patmatch.c printf.c resource.c sha1.c sha256.c sha512.c slab.c slists.c tbf.c xmalloc.c
++src := bitops.c checksum.c event.c idm.c ip.c lists.c mac.c md5.c mempool.c net.c patmatch.c printf.c resource.c sha1.c sha256.c sha512.c slab.c slists.c tbf.c xmalloc.c
 +obj := $(src-o-files)
 +$(all-daemon)
diff --cc lib/birdlib.h
index 188e59b2f89f598f46b209026ee3fbacdb5482c4,37337078d4bb99fb909421fb16e876ab5cecbeef..ddc963f4776d6a8a958f35bab6cab39b0e396c8b
@@@ -63,7 -62,14 +63,6 @@@ static inline int u64_cmp(u64 i1, u64 i
  #define UNUSED __attribute__((unused))
  #define PACKED __attribute__((packed))
  
 -#ifdef IPV6
 -#define UNUSED4
 -#define UNUSED6 UNUSED
 -#else
 -#define UNUSED4 UNUSED
 -#define UNUSED6
 -#endif
--
  /* Microsecond time */
  
  typedef s64 btime;
diff --cc lib/hash.h
index c2fd8bca5655f6a1c31a030d1967cdca3921cf62,4239b1d8991ee495f0f92e18bef1a679f69397c4..b37d8fa5f75f4d5a12e0547d8c9d39ae124e25c0
  
  #define HASH_WALK_FILTER_END } while (0)
  
- mem_hash_mix(u64 *h, void *p, int s)
++
 +static inline void
 +mem_hash_init(u64 *h)
 +{
 +  *h = 0x001047d54778bcafULL;
 +}
 +
 +static inline void
-   
++mem_hash_mix(u64 *h, void *p, uint s)
 +{
 +  const u64 multiplier = 0xb38bc09a61202731ULL;
 +  const char *pp = p;
 +  uint i;
++
 +  for (i=0; i<s/4; i++)
 +    *h = *h * multiplier + ((const u32 *)pp)[i];
- mem_hash(void *p, int s)
++
 +  for (i=s & ~0x3; i<s; i++)
 +    *h = *h * multiplier + pp[i];
 +}
 +
 +static inline uint
 +mem_hash_value(u64 *h)
 +{
 +  return ((*h >> 32) ^ (*h & 0xffffffff));
 +}
 +
 +static inline uint
++mem_hash(void *p, uint s)
 +{
 +  static u64 h;
 +  mem_hash_init(&h);
 +  mem_hash_mix(&h, p, s);
 +  return mem_hash_value(&h);
 +}
 +
+ #endif
diff --cc lib/idm.c
index 16d0e855ef3a972c25ab93d2817a8613d8d8fd89,0000000000000000000000000000000000000000..66e311c6a885077bc43a1a23e01bc066ebff3b0d
mode 100644,000000..100644
--- /dev/null
+++ b/lib/idm.c
@@@ -1,76 -1,0 +1,76 @@@
-  found:
 +/*
 + *    BIRD Library -- ID Map
 + *
 + *    (c) 2013--2015 Ondrej Zajicek <santiago@crfreenet.org>
 + *    (c) 2013--2015 CZ.NIC z.s.p.o.
 + *
 + *    Can be freely distributed and used under the terms of the GNU GPL.
 + */
 +
 +#include <stdlib.h>
 +
 +#include "nest/bird.h"
 +#include "lib/idm.h"
 +#include "lib/resource.h"
 +#include "lib/string.h"
 +
 +
 +void
 +idm_init(struct idm *m, pool *p, uint size)
 +{
 +  m->pos = 0;
 +  m->used = 1;
 +  m->size = size;
 +  m->data = mb_allocz(p, m->size * sizeof(u32));
 +
 +  /* ID 0 is reserved */
 +  m->data[0] = 1;
 +}
 +
 +static inline int u32_cto(uint x) { return ffs(~x) - 1; }
 +
 +u32
 +idm_alloc(struct idm *m)
 +{
 +  uint i, j;
 +
 +  for (i = m->pos; i < m->size; i++)
 +    if (m->data[i] != 0xffffffff)
 +      goto found;
 +
 +  /* If we are at least 7/8 full, expand */
 +  if (m->used > (m->size * 28))
 +  {
 +    m->size *= 2;
 +    m->data = mb_realloc(m->data, m->size * sizeof(u32));
 +    memset(m->data + i, 0, (m->size - i) * sizeof(u32));
 +    goto found;
 +  }
 +
 +  for (i = 0; i < m->pos; i++)
 +    if (m->data[i] != 0xffffffff)
 +      goto found;
 +
 +  ASSERT(0);
 +
++found:
 +  ASSERT(i < 0x8000000);
 +
 +  m->pos = i;
 +  j = u32_cto(m->data[i]);
 +
 +  m->data[i] |= (1 << j);
 +  m->used++;
 +  return 32 * i + j;
 +}
 +
 +void
 +idm_free(struct idm *m, u32 id)
 +{
 +  uint i = id / 32;
 +  uint j = id % 32;
 +
 +  ASSERT((i < m->size) && (m->data[i] & (1 << j)));
 +  m->data[i] &= ~(1 << j);
 +  m->used--;
 +}
diff --cc lib/socket.h
Simple merge
diff --cc nest/config.Y
index 2a746657bbb702b237b817ffa4a5afa225a5b3fa,878224fea4baabc7a9460689da5562a0df5f019b..776e5d161610bcaf7dc038f8ce2abb3343610bde
@@@ -65,10 -56,10 +66,11 @@@ CF_DECL
  
  CF_KEYWORDS(ROUTER, ID, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
  CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE, STATES, ROUTES, FILTERS)
 +CF_KEYWORDS(IPV4, IPV6, VPN4, VPN6, ROA4, ROA6)
  CF_KEYWORDS(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED)
  CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
- CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, NOEXPORT, GENERATE) /* ,ROA */
+ CF_KEYWORDS(ALGORITHM, KEYED, HMAC, MD5, SHA1, SHA256, SHA384, SHA512)
 -CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, NOEXPORT, GENERATE, ROA)
++CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, NOEXPORT, GENERATE)
  CF_KEYWORDS(LISTEN, BGP, V6ONLY, DUAL, ADDRESS, PORT, PASSWORDS, DESCRIPTION, SORTED)
  CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC, CLASS, DSCP)
  CF_KEYWORDS(GRACEFUL, RESTART, WAIT, MAX, FLUSH, AS)
@@@ -85,11 -76,12 +87,11 @@@ CF_ENUM(T_ENUM_ROA, ROA_, UNKNOWN, VALI
  %type <r> rtable
  %type <s> optsym
  %type <ra> r_args
 -%type <ro> roa_args
 -%type <rot> roa_table_arg
  %type <sd> sym_args
- %type <i> proto_start echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_mode limit_action net_type table_sorted tos
 -%type <i> proto_start echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_mode roa_mode limit_action tab_sorted tos password_algorithm
++%type <i> proto_start echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_mode limit_action net_type table_sorted tos password_algorithm
  %type <ps> proto_patt proto_patt2
 -%type <g> limit_spec
 +%type <cc> channel_start proto_channel
 +%type <cl> limit_spec
  
  CF_GRAMMAR
  
diff --cc nest/password.h
index cbf80b99ae8d4db1c527fdcd059158f9cc7f76f8,f21483c4dd2c0e77a7bf5f3e2632654db48d7141..78244985ab27e31c091289b55ef730501c729d4d
@@@ -9,7 -9,8 +9,8 @@@
  
  #ifndef PASSWORD_H
  #define PASSWORD_H
 -#include "lib/timer.h"
 +#include "sysdep/unix/timer.h"
  
  struct password_item {
    node n;
diff --cc nest/route.h
index a536def7be50ae56d32c9fbccf484c2901db1b3c,383f4def09420c1539bb85ad511fdc0b5cc8fa7c..f2e883b60d5bbd96275cb05a3fbe729f9e00570b
@@@ -277,20 -268,16 +277,19 @@@ void rt_commit(struct config *new, stru
  void rt_lock_table(rtable *);
  void rt_unlock_table(rtable *);
  void rt_setup(pool *, rtable *, char *, struct rtable_config *);
 -static inline net *net_find(rtable *tab, ip_addr addr, unsigned len) { return (net *) fib_find(&tab->fib, &addr, len); }
 -static inline net *net_get(rtable *tab, ip_addr addr, unsigned len) { return (net *) fib_get(&tab->fib, &addr, len); }
 +static inline net *net_find(rtable *tab, const net_addr *addr) { return (net *) fib_find(&tab->fib, addr); }
 +static inline net *net_get(rtable *tab, const net_addr *addr) { return (net *) fib_get(&tab->fib, addr); }
 +void *net_route(rtable *tab, const net_addr *n);
 +int net_roa_check(rtable *tab, const net_addr *n, u32 asn);
  rte *rte_find(net *net, struct rte_src *src);
  rte *rte_get_temp(struct rta *);
 -void rte_update2(struct announce_hook *ah, net *net, rte *new, struct rte_src *src);
 -static inline void rte_update(struct proto *p, net *net, rte *new) { rte_update2(p->main_ahook, net, new, p->main_source); }
 -int rt_examine(rtable *t, ip_addr prefix, int pxlen, struct proto *p, struct filter *filter);
 -rte *rt_export_merged(struct announce_hook *ah, net *net, rte **rt_free, struct ea_list **tmpa, linpool *pool, int silent);
 -void rt_refresh_begin(rtable *t, struct announce_hook *ah);
 -void rt_refresh_end(rtable *t, struct announce_hook *ah);
 +void rte_update2(struct channel *c, net_addr *n, rte *new, struct rte_src *src);
 +/* rte_update() moved to protocol.h to avoid dependency conflicts */
- void rte_discard(rtable *tab, rte *old);
 +int rt_examine(rtable *t, net_addr *a, struct proto *p, struct filter *filter);
 +rte *rt_export_merged(struct channel *c, net *net, rte **rt_free, struct ea_list **tmpa, linpool *pool, int silent);
 +void rt_refresh_begin(rtable *t, struct channel *c);
 +void rt_refresh_end(rtable *t, struct channel *c);
 +void rt_schedule_prune(rtable *t);
  void rte_dump(rte *);
  void rte_free(rte *);
  rte *rte_do_cow(rte *);
diff --cc nest/rt-attr.c
Simple merge
diff --cc nest/rt-table.c
index eb9dc3a503564311bcaa3b49953a257c65af33ba,c6e48c38016eb18ed2bceae64b97e0dae2835a8b..4260e4932c94c559c9462ef5be2f7ac400a3977b
@@@ -63,155 -65,34 +63,155 @@@ make_tmp_attrs(struct rte *rt, struct l
  {
    struct ea_list *(*mta)(struct rte *rt, struct linpool *pool);
    mta = rt->attrs->src->proto->make_tmp_attrs;
-   return mta ? mta(rt, rte_update_pool) : NULL;
+   return mta ? mta(rt, pool) : NULL;
  }
  
 +
  /* Like fib_route(), but skips empty net entries */
 -static net *
 -net_route(rtable *tab, ip_addr a, int len)
 +static inline void *
 +net_route_ip4(struct fib *f, net_addr_ip4 *n)
  {
 -  ip_addr a0;
 -  net *n;
 +  net *r;
 +
 +  while (r = fib_find(f, (net_addr *) n),
 +       !(r && rte_is_valid(r->routes)) && (n->pxlen > 0))
 +  {
 +    n->pxlen--;
 +    ip4_clrbit(&n->prefix, n->pxlen);
 +  }
 +
 +  return r;
 +}
 +
 +static inline void *
 +net_route_ip6(struct fib *f, net_addr_ip6 *n)
 +{
 +  net *r;
 +
 +  while (r = fib_find(f, (net_addr *) n),
 +       !(r && rte_is_valid(r->routes)) && (n->pxlen > 0))
 +  {
 +    n->pxlen--;
 +    ip6_clrbit(&n->prefix, n->pxlen);
 +  }
 +
 +  return r;
 +}
 +
 +void *
 +net_route(rtable *tab, const net_addr *n)
 +{
 +  ASSERT(tab->addr_type == n->type);
 +
 +  net_addr *n0 = alloca(n->length);
 +  net_copy(n0, n);
 +
 +  switch (n->type)
 +  {
 +  case NET_IP4:
 +  case NET_VPN4:
 +  case NET_ROA4:
 +    return net_route_ip4(&tab->fib, (net_addr_ip4 *) n0);
  
 -  while (len >= 0)
 +  case NET_IP6:
 +  case NET_VPN6:
 +  case NET_ROA6:
 +    return net_route_ip6(&tab->fib, (net_addr_ip6 *) n0);
 +
 +  default:
 +    return NULL;
 +  }
 +}
 +
 +
 +static int
 +net_roa_check_ip4(rtable *tab, const net_addr_ip4 *px, u32 asn)
 +{
 +  struct net_addr_roa4 n = NET_ADDR_ROA4(px->prefix, px->pxlen, 0, 0);
 +  struct fib_node *fn;
 +  int anything = 0;
 +
 +  while (1)
 +  {
 +    for (fn = fib_get_chain(&tab->fib, (net_addr *) &n); fn; fn = fn->next)
      {
 -      a0 = ipa_and(a, ipa_mkmask(len));
 -      n = fib_find(&tab->fib, &a0, len);
 -      if (n && rte_is_valid(n->routes))
 -      return n;
 -      len--;
 +      net_addr_roa4 *roa = (void *) fn->addr;
 +      net *r = fib_node_to_user(&tab->fib, fn);
 +
 +      if (net_equal_prefix_roa4(roa, &n) && rte_is_valid(r->routes))
 +      {
 +      anything = 1;
 +      if (asn && (roa->asn == asn) && (roa->max_pxlen >= px->pxlen))
 +        return ROA_VALID;
 +      }
      }
 -  return NULL;
 +
 +    if (n.pxlen == 0)
 +      break;
 +
 +    n.pxlen--;
 +    ip4_clrbit(&n.prefix, n.pxlen);
 +  }
 +
 +  return anything ? ROA_INVALID : ROA_UNKNOWN;
  }
  
 -static void
 -rte_init(struct fib_node *N)
 +static int
 +net_roa_check_ip6(rtable *tab, const net_addr_ip6 *px, u32 asn)
  {
 -  net *n = (net *) N;
 +  struct net_addr_roa6 n = NET_ADDR_ROA6(px->prefix, px->pxlen, 0, 0);
 +  struct fib_node *fn;
 +  int anything = 0;
 +
 +  while (1)
 +  {
 +    for (fn = fib_get_chain(&tab->fib, (net_addr *) &n); fn; fn = fn->next)
 +    {
 +      net_addr_roa6 *roa = (void *) fn->addr;
 +      net *r = fib_node_to_user(&tab->fib, fn);
  
 -  N->flags = 0;
 -  n->routes = NULL;
 +      if (net_equal_prefix_roa6(roa, &n) && rte_is_valid(r->routes))
 +      {
 +      anything = 1;
 +      if (asn && (roa->asn == asn) && (roa->max_pxlen >= px->pxlen))
 +        return ROA_VALID;
 +      }
 +    }
 +
 +    if (n.pxlen == 0)
 +      break;
 +
 +    n.pxlen--;
 +    ip6_clrbit(&n.prefix, n.pxlen);
 +  }
 +
 +  return anything ? ROA_INVALID : ROA_UNKNOWN;
 +}
 +
 +/**
 + * roa_check - check validity of route origination in a ROA table
 + * @tab: ROA table
 + * @n: network prefix to check
 + * @asn: AS number of network prefix
 + *
 + * Implements RFC 6483 route validation for the given network prefix. The
 + * procedure is to find all candidate ROAs - ROAs whose prefixes cover the given
 + * network prefix. If there is no candidate ROA, return ROA_UNKNOWN. If there is
 + * a candidate ROA with matching ASN and maxlen field greater than or equal to
 + * the given prefix length, return ROA_VALID. Otherwise, return ROA_INVALID. If
 + * caller cannot determine origin AS, 0 could be used (in that case ROA_VALID
 + * cannot happen). Table @tab must have type NET_ROA4 or NET_ROA6, network @n
 + * must have type NET_IP4 or NET_IP6, respectively.
 + */
 +int
 +net_roa_check(rtable *tab, const net_addr *n, u32 asn)
 +{
 +  if ((tab->addr_type == NET_ROA4) && (n->type == NET_IP4))
 +    return net_roa_check_ip4(tab, (const net_addr_ip4 *) n, asn);
 +  else if ((tab->addr_type == NET_ROA6) && (n->type == NET_IP6))
 +    return net_roa_check_ip6(tab, (const net_addr_ip6 *) n, asn);
 +  else
 +    return ROA_UNKNOWN;       /* Should not happen */
  }
  
  /**
@@@ -1686,17 -1598,16 +1686,17 @@@ again
  
      rescan:
        for (e=n->routes; e; e=e->next)
 -      if (e->sender->proto->flushing || (e->flags & REF_DISCARD))
 +      if (e->sender->flush_active || (e->flags & REF_DISCARD))
          {
 -          if (*limit <= 0)
 +          if (limit <= 0)
              {
 -              FIB_ITERATE_PUT(fit, fn);
 -              return 0;
 +              FIB_ITERATE_PUT(fit);
 +              ev_schedule(tab->rt_event);
 +              return;
              }
  
-           rte_discard(tab, e);
+           rte_discard(e);
 -          (*limit)--;
 +          limit--;
  
            goto rescan;
          }
@@@ -2166,11 -2104,11 +2166,11 @@@ hc_remove(struct hostcache *hc, struct 
  static void
  hc_alloc_table(struct hostcache *hc, unsigned order)
  {
-   unsigned hsize = 1 << order;
+   uint hsize = 1 << order;
    hc->hash_order = order;
 -  hc->hash_shift = 16 - order;
 +  hc->hash_shift = 32 - order;
-   hc->hash_max = (order >= HC_HI_ORDER) ? ~0 : (hsize HC_HI_MARK);
-   hc->hash_min = (order <= HC_LO_ORDER) ?  0 : (hsize HC_LO_MARK);
+   hc->hash_max = (order >= HC_HI_ORDER) ? ~0U : (hsize HC_HI_MARK);
+   hc->hash_min = (order <= HC_LO_ORDER) ?  0U : (hsize HC_LO_MARK);
  
    hc->hash_table = mb_allocz(rt_table_pool, hsize * sizeof(struct hostentry *));
  }
diff --cc proto/bfd/bfd.c
Simple merge
diff --cc proto/bfd/bfd.h
Simple merge
Simple merge
diff --cc proto/bgp/bgp.c
Simple merge
Simple merge
Simple merge
index 3fbb61673f709458f9df4153fd8ca402784efadb,e00487dc6d40ce39e5f28646d45d6610a7c52b98..2c55155d0f8a69f022f25ae815838185d4fcaa18
@@@ -222,9 -222,12 +222,12 @@@ ospf_receive_hello(struct ospf_packet *
      rcv_priority = ps->priority;
  
      int pxlen = u32_masklen(ntohl(ps->netmask));
+     if (pxlen < 0)
+       DROP("prefix garbled", ntohl(ps->netmask));
      if ((ifa->type != OSPF_IT_VLINK) &&
        (ifa->type != OSPF_IT_PTP) &&
-       (pxlen != ifa->addr->prefix.pxlen))
 -      ((uint) pxlen != ifa->addr->pxlen))
++      ((uint) pxlen != ifa->addr->prefix.pxlen))
        DROP("prefix length mismatch", pxlen);
  
      neighbors = ps->neighbors;
index 6ef24ffe5bfb2a9214cc4fd108cbe8f3a5c12b20,280fa4c1e718ad6e79221e05ce35bcf5c64b29ec..675cf76dc8d271391fab05a9ee1378531a823851
@@@ -51,6 -52,18 +52,20 @@@ ifa_tx_length(struct ospf_iface *ifa
    return ifa->cf->tx_length ?: ifa->iface->mtu;
  }
  
 -  uint hlen = SIZE_OF_IP_HEADER;
+ static inline uint
+ ifa_tx_hdrlen(struct ospf_iface *ifa)
+ {
++  struct ospf_proto *p = ifa->oa->po;
++
++  uint hlen = ospf_is_v2(p) ? IP4_HEADER_LENGTH : IP6_HEADER_LENGTH;
+   /* Relevant just for OSPFv2 */
+   if (ifa->autype == OSPF_AUTH_CRYPT)
+     hlen += max_mac_length(ifa->passwords);
+   return hlen;
+ }
  static inline uint
  ifa_bufsize(struct ospf_iface *ifa)
  {
Simple merge
Simple merge
Simple merge
diff --cc proto/ospf/rt.c
Simple merge
index 86e39d75253ddd29bfdb368a8bee0ff4cf7df086,341eff87eb5a6fed39b2f99bd37e90129deaeb72..aaaf2e8e3a687dcc23e576207d093822f3d4eb92
@@@ -513,8 -513,9 +513,9 @@@ ospf_update_lsadb(struct ospf_proto *p
    }
  }
  
 -static inline u32
 -ort_to_lsaid(struct ospf_proto *p UNUSED4 UNUSED6, ort *nf)
 +static u32
 +ort_to_lsaid(struct ospf_proto *p, ort *nf)
  {
    /*
     * In OSPFv2, We have to map IP prefixes to u32 in such manner that resulting
index d40b3f91e1170bfa32cb50221c5eac31fc95b8a7,6ef803222329d82854d37777609891e70eaa4bcb..8924c2000f51d6feb158331c400e53800de170dc
@@@ -191,9 -257,10 +191,9 @@@ pipe_reconfigure(struct proto *P, struc
  }
  
  static void
--pipe_copy_config(struct proto_config *dest, struct proto_config *src)
++pipe_copy_config(struct proto_config *dest UNUSED, struct proto_config *src UNUSED)
  {
    /* Just a shallow copy, not many items here */
 -  proto_copy_rest(dest, src, sizeof(struct pipe_config));
  }
  
  static void
Simple merge
Simple merge
Simple merge
index f89bb1783942787f17915ef40208323cc5937b8a,468927e6e24d4f7a074435d76d1fd67bba819207..9dc492b76e9e2c0c00a787d4228662ac37791f71
@@@ -9,10 -9,8 +9,10 @@@
   *    Can be freely distributed and used under the terms of the GNU GPL.
   */
  
 +#undef LOCAL_DEBUG
 +
  #include "rip.h"
- #include "lib/md5.h"
+ #include "lib/mac.h"
  
  
  #define RIP_CMD_REQUEST               1       /* want info */
@@@ -132,7 -129,7 +130,7 @@@ rip_put_block(struct rip_proto *p, byt
  }
  
  static inline void
- rip_put_next_hop(struct rip_proto *p, byte *pos, struct rip_block *rte)
 -rip_put_next_hop(struct rip_proto *p UNUSED, byte *pos, struct rip_block *rte UNUSED4)
++rip_put_next_hop(struct rip_proto *p UNUSED, byte *pos, struct rip_block *rte)
  {
    struct rip_block_ng *block = (void *) pos;
    block->prefix = ip6_hton(ipa_to_ip6(rte->next_hop));
diff --cc proto/rip/rip.c
Simple merge
diff --cc proto/rip/rip.h
Simple merge
Simple merge
index 3440ed637e56a5db4da4eb730cf77c9c80340d30,9c9df51de527ba0191ff88ebeaee993fa99618e7..d2372a3d480acf9f19af3150ca52282f69c3aa87
@@@ -1120,9 -1074,9 +1120,9 @@@ kif_sys_shutdown(struct kif_proto *p
  
  
  struct ifa *
- kif_get_primary_ip(struct iface *i)
 -kif_get_primary_ip(struct iface *i UNUSED6)
++kif_get_primary_ip(struct iface *i UNUSED)
  {
 -#ifndef IPV6
 +#if 0
    static int fd = -1;
    
    if (fd < 0)
index 870cdf2ce9ae5bfc02793e05b56deb4944be4353,353ffcec56c601ef9757776d97b71e1b125450da..ed667e8049987d23e76bd2b15c4d69b25851be30
@@@ -44,8 -44,8 +44,9 @@@ struct krt_state 
  
  static inline void krt_sys_io_init(void) { }
  static inline void krt_sys_init(struct krt_proto *p UNUSED) { }
 +static inline void krt_sys_postconfig(struct krt_config *x UNUSED) { }
  
 -static inline int krt_sys_get_attr(eattr *a UNUSED, byte *buf UNUSED, int buflen UNUSED) { return 0; }
 +static inline int krt_sys_get_attr(eattr *a UNUSED, byte *buf UNUSED, int buflen UNUSED) { return GA_UNKNOWN; }
  
  #endif
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge