config.Y 3.47 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
/*
 *	BIRD -- The Resource Public Key Infrastructure (RPKI) to Router Protocol
 *
 *	(c) 2015 CZ.NIC
 *
 *	Can be freely distributed and used under the terms of the GNU GPL.
 */

CF_HDR

#include "proto/rpki/rpki.h"

CF_DEFINES

#define RPKI_CFG ((struct rpki_config *) this_proto)
#define RPKI_TR_SSH_CFG ((struct rpki_tr_ssh_config *) RPKI_CFG->tr_config.spec)

static void
rpki_check_unused_hostname(void)
{
  if (RPKI_CFG->hostname != NULL)
    cf_error("Only one cache server per protocol allowed");
}

static void
rpki_check_unused_transport(void)
{
  if (RPKI_CFG->tr_config.spec != NULL)
    cf_error("At the most one transport per protocol allowed");
}

CF_DECLS

CF_KEYWORDS(RPKI, REMOTE, BIRD, PRIVATE, PUBLIC, KEY, TCP, SSH, TRANSPORT, USER,
	    RETRY, REFRESH, EXPIRE, KEEP)

%type <i> rpki_keep_interval

CF_GRAMMAR

CF_ADDTO(proto, rpki_proto)

rpki_proto_start: proto_start RPKI {
  this_proto = proto_config_new(&proto_rpki, $1);
  RPKI_CFG->retry_interval = RPKI_RETRY_INTERVAL;
  RPKI_CFG->refresh_interval = RPKI_REFRESH_INTERVAL;
  RPKI_CFG->expire_interval = RPKI_EXPIRE_INTERVAL;
};

rpki_proto: rpki_proto_start proto_name '{' rpki_proto_opts '}' { rpki_check_config(RPKI_CFG); };

rpki_proto_opts:
   /* empty */
 | rpki_proto_opts rpki_proto_item ';'
 ;

rpki_proto_item:
   proto_item
 | proto_channel
 | REMOTE rpki_cache_addr
 | REMOTE rpki_cache_addr rpki_proto_item_port
 | rpki_proto_item_port
 | TRANSPORT rpki_transport
 | REFRESH rpki_keep_interval expr {
     if (rpki_check_refresh_interval($3))
       cf_error(rpki_check_refresh_interval($3));
     RPKI_CFG->refresh_interval = $3;
     RPKI_CFG->keep_refresh_interval = $2;
   }
 | RETRY rpki_keep_interval expr {
     if (rpki_check_retry_interval($3))
       cf_error(rpki_check_retry_interval($3));
     RPKI_CFG->retry_interval = $3;
     RPKI_CFG->keep_retry_interval = $2;
   }
 | EXPIRE rpki_keep_interval expr {
     if (rpki_check_expire_interval($3))
       cf_error(rpki_check_expire_interval($3));
     RPKI_CFG->expire_interval = $3;
     RPKI_CFG->keep_expire_interval = $2;
   }
 ;

rpki_keep_interval:
 /* empty */ { $$ = 0; }
 | KEEP { $$ = 1; }
 ;

rpki_proto_item_port: PORT expr { check_u16($2); RPKI_CFG->port = $2; };

rpki_cache_addr:
   text {
     rpki_check_unused_hostname();
     RPKI_CFG->hostname = $1;
   }
 | ipa {
     rpki_check_unused_hostname();
     RPKI_CFG->ip = $1;
     /* Ensure hostname is filled */
     char *hostname = cfg_allocz(sizeof(INET6_ADDRSTRLEN + 1));
     bsnprintf(hostname, INET6_ADDRSTRLEN+1, "%I", RPKI_CFG->ip);
     RPKI_CFG->hostname = hostname;
   }
 ;

rpki_transport:
   TCP rpki_transport_tcp_init
 | SSH rpki_transport_ssh_init '{' rpki_transport_ssh_opts '}' rpki_transport_ssh_check
 ;

rpki_transport_tcp_init:
{
  rpki_check_unused_transport();
  RPKI_CFG->tr_config.spec = cfg_allocz(sizeof(struct rpki_tr_tcp_config));
  RPKI_CFG->tr_config.type = RPKI_TR_TCP;
};

rpki_transport_ssh_init:
{
  rpki_check_unused_transport();
  RPKI_CFG->tr_config.spec = cfg_allocz(sizeof(struct rpki_tr_ssh_config));
  RPKI_CFG->tr_config.type = RPKI_TR_SSH;
};

rpki_transport_ssh_opts:
   /* empty */
 | rpki_transport_ssh_opts rpki_transport_ssh_item ';'
 ;

rpki_transport_ssh_item:
   BIRD PRIVATE KEY text  { RPKI_TR_SSH_CFG->bird_private_key = $4; }
 | REMOTE PUBLIC KEY text { RPKI_TR_SSH_CFG->cache_public_key = $4; }
 | USER text              { RPKI_TR_SSH_CFG->user = $2; }
 ;

rpki_transport_ssh_check:
{
  if (RPKI_TR_SSH_CFG->user == NULL)
    cf_error("User must be set");
};

CF_CODE

CF_END