コード例 #1
0
ファイル: qif.c プロジェクト: deepfield/MRT
static int
qif_set_qif (srsvp_t *srsvp, srsvp_interface_t *vif, int type)
{
    u_char msgbuf[1024];
    int ret;
    struct rt_msghdr *rtm = (struct rt_msghdr *) msgbuf;
    struct qos_msghdr *qosm = (struct qos_msghdr *) (rtm + 1);
    sockunion_t *su = (sockunion_t *) (qosm + 1);
    prefix_t *gateway;

    memset (rtm, 0, sizeof (*rtm));
    memset (qosm, 0, sizeof (*qosm));

    assert (type == RTM_QIF_ADD || type == RTM_QIF_DEL);
    rtm->rtm_type = type;
    rtm->rtm_msglen = sizeof (*rtm) + sizeof (*qosm);

    qosm->qifi = vif->interface->index;
    if (type == RTM_QIF_ADD) {
        qosm->flags = QOS_QIF_MULTI;
        qosm->queue_alg = (vif->qalg)? vif->qalg: ALTQ_PRQ; /* XXX */
        qosm->qos.rdly = (vif->qlimit >= 0)? vif->qlimit: 200; /* XXX */
    }

    gateway = vif->prefix;
    assert (gateway);
#ifdef HAVE_IPV6
    if (gateway->family == AF_INET6) {
        memset (su, 0, sizeof (su->sin6));
	su->sin6.sin6_family = AF_INET6;
	su->sin6.sin6_len = sizeof (su->sin6);
	memcpy (&su->sin6.sin6_addr, prefix_tochar (gateway), 16);
    	rtm->rtm_msglen += sizeof (su->sin6);
    }
    else
#endif /* HAVE_IPV6 */
    {
        memset (su, 0, sizeof (su->sin));
        su->sin.sin_family = AF_INET;
	su->sin.sin_len = sizeof (su->sin);
	memcpy (&su->sin.sin_addr, prefix_tochar (gateway), 4);
    	rtm->rtm_msglen += sizeof (su->sin);
    }

    if ((ret = qif_sendmsg (rtm)) < 0) {
        trace (TR_ERROR, MRT->trace, "QIF qif_set_qif (%m)\n");
    }
    else {
        trace (TR_INFO, MRT->trace, "QIF %s:%d %s\n",
		    vif->interface->name, vif->interface->index,
	    (type == RTM_QIF_ADD)? "created": "removed");
    }
    return (ret);
}
コード例 #2
0
ファイル: qif.c プロジェクト: deepfield/MRT
int
qif_notify (srsvp_t *srsvp, srsvp_flow_t *flow, int eno)
{
    u_char msgbuf[1024];
    int ret;
    struct rt_msghdr *rtm = (struct rt_msghdr *) msgbuf;
    struct qos_msghdr *qosm = (struct qos_msghdr *) (rtm + 1);
    qos_rtflow_t *qosr = (qos_rtflow_t *) (qosm + 1);

    memset (rtm, 0, sizeof (*rtm));
    memset (qosm, 0, sizeof (*qosm));

    rtm->rtm_type = RTM_FLOW_EXCEPT;
    rtm->rtm_msglen = sizeof (*rtm) + sizeof (*qosm);

    assert (flow);
    assert (flow->sender);
    assert (flow->destin);
    assert (flow->sender->family == flow->destin->family);
#ifdef HAVE_IPV6
    if (flow->upstream->prefix->family == AF_INET6) {
        memset (qosr, 0, sizeof (qosr->fin6));
	qosr->fin6.family = AF_INET6;
	qosr->fin6.len = sizeof (qosr->fin6);
	qosr->fin6.proto = flow->proto;
	memcpy (&qosr->fin6.src, prefix_tochar (flow->sender), 16);
	memcpy (&qosr->fin6.dest, prefix_tochar (flow->destin), 16);
	qosr->fin6.sport = htons (flow->sport);
	qosr->fin6.dport = htons (flow->dport);
    	rtm->rtm_msglen += sizeof (qosr->fin6);
    }
    else
#endif /* HAVE_IPV6 */
    {
        memset (qosr, 0, sizeof (qosr->fin));
	qosr->fin.family = AF_INET;
	qosr->fin.len = sizeof (qosr->fin);
	qosr->fin.proto = flow->proto;
	memcpy (&qosr->fin.src, prefix_tochar (flow->sender), 4);
	memcpy (&qosr->fin.dest, prefix_tochar (flow->destin), 4);
	qosr->fin.sport = htons (flow->sport);
	qosr->fin.dport = htons (flow->dport);
    	rtm->rtm_msglen += sizeof (qosr->fin);
    }

    if ((ret = qif_sendmsg (rtm)) < 0) {
        trace (TR_ERROR, MRT->trace, "QIF qif_notify (%m)\n");
    }
    return (ret);
}
コード例 #3
0
ファイル: alist.c プロジェクト: job/irrd
/*
 * return 1 if permit, 0 if denied, -1 if not matched
 */
int
apply_condition (condition_t *condition, prefix_t *prefix)
{
    assert (condition);

    if (condition->prefix == NULL) /* all */
        return (condition->permit);

    /* family the same */
    if ((prefix->family == condition->prefix->family) &&
            /* refine */
            ((condition->refine && prefix->bitlen > condition->prefix->bitlen) ||
             /* no refine or exact */
             ((!condition->refine || condition->exact) &&
              prefix->bitlen == condition->prefix->bitlen)) &&
            /* prefix compare up to bitlen with wildcard */
            byte_compare (prefix_tochar (prefix),
                          prefix_tochar (condition->prefix),
                          condition->prefix->bitlen,
                          (condition->wildcard)?
                          prefix_tochar (condition->wildcard): NULL))
        return (condition->permit);
    return (-1);
}
コード例 #4
0
ファイル: route_atob.c プロジェクト: deepfield/MRT
static void 
read_ascii (FILE *fd, io_t *IO)
{
    LINKED_LIST *ll_ann, *ll_with;
    bgp_attr_t *attr;
    int announce_flag = 0;
    int line_num = 0;
    int have_data = 0;
    int have_data2 = 0;
    time_t tstamp = 0;
    int type = 0;
    int subtype = 0;
    int bgptype = 0;
    int newtype = 0;
    gateway_t *gateway_from = NULL;
    gateway_t *gateway_to = NULL;
    int first = 1;
    u_char bgp_packet[BGPMAXPACKETSIZE], *bp = bgp_packet;
    u_char buffer[MAX_MSG_SIZE], *buffer_p = buffer;
    u_char *end = buffer + sizeof (buffer);
    int eof = 0;
    buffer_t *stdbuf;

    int state1 = 0, state2 = 0;

    int version = 0, as = 0, holdtime = 0, optlen = 0;
    u_long id = 0;

    int code = 0, subcode = 0;

    int viewno = 0;
    char *filename = NULL;

    prefix_t *route_prefix = NULL;
    time_t originated = 0;
    u_long status = 0;
    int seq_num = 0;

    attr = bgp_new_attr (PROTO_BGP);
    ll_ann = LL_Create (LL_DestroyFunction, Deref_Prefix, 0);
    ll_with = LL_Create (LL_DestroyFunction, Deref_Prefix, 0);

    stdbuf = New_Buffer_Stream (fd);
    for (;;) {
        char *line = NULL, *ret = NULL;
	int len = 0;
        int ok = 0;
	char *cp;

        if (buffer_gets (stdbuf) <= 0) {
	    eof++;
	}
	else {
	    len = buffer_data_len (stdbuf);
	    line = buffer_data (stdbuf);

	    if (line[len - 1] == '\n') {
	        line[len - 1] = '\0';
	        len--;
	    }
	    trace (TR_TRACE, MRT->trace, "++%s\n", line);
            line_num++;

	    if ((cp = strpbrk (line, "#!")) != NULL) {
	        *cp = '\0';
	        len = cp - line;
	    }

	    if (first && nulline (line))
	        continue;
	    first = 0;
	}
    
	if (eof || nulline (line)) {
	    if (have_data && have_data2) {
		trace (TR_ERROR, MRT->trace, "Mixture of two formats\n");
		goto error;
	    }
	    if (bgptype == BGP_UPDATE && have_data) {
		flushout (IO, tstamp, type, subtype, attr, ll_ann, ll_with, 
			  gateway_to);
	    }
	    else if (have_data2) {
		flushout2 (IO, tstamp, type, subtype, 
			   bgp_packet, bp - bgp_packet, 
			   gateway_from, gateway_to);
	    }
    	    else if (bgptype == BGP_KEEPALIVE) {
		if (type == MSG_PROTOCOL_BGP4MP) {
		    memset (bgp_packet, 0xff, BGP_HEADER_MARKER_LEN);
	  	    BGP_PUT_HDRTYPE (bgptype, bgp_packet);
		    bp = bgp_packet + BGP_HEADER_LEN;
	  	    BGP_PUT_HDRLEN (bp - bgp_packet, bgp_packet);
		}
		else {
		    bp = bgp_packet;
		}
		flushout2 (IO, tstamp, type, subtype, 
		   	   bgp_packet, bp - bgp_packet, 
			   gateway_from, gateway_to);
    	    }
    	    else if (bgptype == BGP_OPEN) {
		if (type == MSG_PROTOCOL_BGP4MP) {
		    memset (bgp_packet, 0xff, BGP_HEADER_MARKER_LEN);
	  	    BGP_PUT_HDRTYPE (bgptype, bgp_packet);
		    bp = bgp_packet + BGP_HEADER_LEN;
		}
		else {
		    bp = bgp_packet;
		}
		BGP_PUT_BYTE (version, bp);
		BGP_PUT_SHORT (as, bp);
		BGP_PUT_SHORT (holdtime, bp);
		BGP_PUT_NETLONG (id, bp);
		BGP_PUT_BYTE (0, bp); /* XXX */
		if (type == MSG_PROTOCOL_BGP4MP) {
	  	    BGP_PUT_HDRLEN (bp - bgp_packet, bgp_packet);
		}
		flushout2 (IO, tstamp, type, subtype, 
		 	   bgp_packet, bp - bgp_packet, 
			   gateway_from, gateway_to);
    	    }
    	    else if (bgptype == BGP_NOTIFY) {
		if (type == MSG_PROTOCOL_BGP4MP) {
		    memset (bgp_packet, 0xff, BGP_HEADER_MARKER_LEN);
	  	    BGP_PUT_HDRTYPE (bgptype, bgp_packet);
		    bp = bgp_packet + BGP_HEADER_LEN;
		}
		else {
		    bp = bgp_packet;
		}
		BGP_PUT_BYTE (code, bp);
		BGP_PUT_BYTE (subcode, bp);
		if (type == MSG_PROTOCOL_BGP4MP) {
	  	    BGP_PUT_HDRLEN (bp - bgp_packet, bgp_packet);
		}
		flushout2 (IO, tstamp, type, subtype, 
		 	   bgp_packet, bp - bgp_packet, 
			   gateway_from, gateway_to);
    	    }
	    else if (newtype == BGP4MP_STATE_CHANGE) {
		bp = bgp_packet;
		BGP_PUT_SHORT (state1, bp);
		BGP_PUT_SHORT (state2, bp);
		flushout2 (IO, tstamp, type, subtype, 
		 	   bgp_packet, bp - bgp_packet, 
			   gateway_from, NULL);
	    }
	    else if (newtype == BGP4MP_SNAPSHOT) {
		bp = bgp_packet;
		BGP_PUT_SHORT (viewno, bp);
		if (filename)
		    BGP_PUT_DATA (filename, strlen (filename), bp);
		BGP_PUT_BYTE (0, bp);
    		trace_mrt_header (MRT->trace, tstamp, type, subtype);
    		io_write (IO, tstamp, type, subtype, 
			  bp - bgp_packet, bgp_packet);
	    }
	    else if (newtype == BGP4MP_ENTRY) {
		if (route_prefix != NULL) {
		    buffer_p = bgp_table_dump_entry (buffer_p, end, type, 
						     subtype, viewno, 
				   route_prefix, status, originated, attr);
		}
		if (buffer_p - buffer > 0) {
    		    trace_mrt_header (MRT->trace, tstamp, type, subtype);
    		    io_write (IO, tstamp, type, subtype, 
			      buffer_p - buffer, buffer);
		}
	    }

	    if (eof)
		break;
	if (MRT->force_exit_flag)
	    exit (1);
	    bgp_deref_attr (attr);
	    attr = bgp_new_attr (PROTO_BGP);
	    LL_Clear (ll_ann);
	    LL_Clear (ll_with);

    	    announce_flag = 0;
    	    have_data = 0;
    	    have_data2 = 0;
    	    tstamp = 0;
    	    type = 0;
    	    subtype = 0;
    	    bgptype = 0;
    	    newtype = 0;
    	    gateway_to = NULL;
    	    gateway_from = NULL;
    	    route_prefix = NULL;
	    seq_num = 0;
    	    first = 1;
    	    if (filename)
		free (filename);
	    filename = NULL;
	    continue;
	}

    if (have_data) {
	/* a prefix -- line begins with a space */
	if (isspace (line[0])) {
	    prefix_t *prefix;
	    char *cp = line +1;

	    while (isspace (*cp))
		cp++;
	    if ((prefix = ascii2prefix (0, cp)) != NULL) {
		if (announce_flag == 1) {
		    LL_Add (ll_ann, prefix);
		}
		else {
		    LL_Add (ll_with, prefix);
		}
	        continue;
	    }
	}
    }

	if (have_data2) {
	    prefix_t *prefix;
	    int num;
	    u_long value;

	    if (isspace (line[0]) &&
		    strpbrk (line, ".:") && strchr (line, '/') &&
		    parse_line (line, "%d %m", &num, &prefix) == 2) {
		u_char *here = bp;
		/* v4 or v6 address with prefixlen */
#ifdef HAVE_IPV6
		if (prefix->family == AF_INET6)
		    BGP_PUT_PREFIX6 (prefix->bitlen, prefix_tochar (prefix), 
				     bp);
		else
#endif /* HAVE_IPV6 */
		    BGP_PUT_PREFIX (prefix->bitlen, prefix_tochar (prefix), 
				    bp);
		Deref_Prefix (prefix);
		if (num != bp - here) {
		    trace (TR_ERROR, MRT->trace, 
			   "length was %d but must be %d\n", num, bp - here);
		    goto error;
		}
		continue;
	    }
	    else if (isspace (line[0]) &&
	    	         strpbrk (line, ".:") && 
		    	 parse_line (line, "%d %M", &num, &prefix) == 2) {
		/* v4 or v6 address w/o prefixlen */
		if (prefix->family == AF_INET6 && num > 16) {
		    trace (TR_ERROR, MRT->trace, 
			   "length was %d but must be less than or equal %d\n",
			    num, 16);
		    Deref_Prefix (prefix);
		    goto error;
		}
		if (prefix->family == AF_INET && num > 4) {
		    trace (TR_ERROR, MRT->trace, 
			   "length was %d but must be less than or equal %d\n",
			    num, 4);
		    Deref_Prefix (prefix);
		    goto error;
		}
		BGP_PUT_DATA (prefix_tochar (prefix), num, bp);
		Deref_Prefix (prefix);
		continue;
	    }
	    else if (isspace (line[0]) &&
	    		parse_line (line, "%d %i", &num, &value) == 2) {
		if (num == 1)
		    BGP_PUT_BYTE (value, bp);
		else if (num == 2)
		    BGP_PUT_SHORT (value, bp);
		else if (num == 4)
		    BGP_PUT_LONG (value, bp);
		else {
		    trace (TR_ERROR, MRT->trace, 
			   "unknown length %d\n", num);
		    goto error;
		}
		continue;
	    }
	}

	if ((ret = checkstradvance (line, "TIME"))) {
	    struct tm tm;
	    if (strptime (ret, "%D %T", &tm)) {
		time_t now;
		time (&now);
		tm.tm_isdst = localtime (&now)->tm_isdst;
		adjust_y2k (&tm);
		tstamp = mktime (&tm);
	    }
	}

	else if ((ret = checkstradvance (line, "TO"))) {
	    int as;
    	    char data[MAXLINE];
	    prefix_t *prefix;
	    if (sscanf (ret, "%s AS%d", data, &as) >= 2 ||
	        sscanf (ret, "AS%d %s", &as, data) >= 2 /* obsolete */) {
		prefix = ascii2prefix (0, data);
		gateway_to = add_gateway (prefix, as, NULL);
		Deref_Prefix (prefix);
	    }
	}

	else if ((ret = checkstradvance (line, "FROM"))) {
	    int as;
    	    char data[MAXLINE];
	    if (sscanf (ret, "%s AS%d", data, &as) >= 2 ||
	        sscanf (ret, "AS%d %s", &as, data) >= 2 /* obsolete */) {
		prefix_t *prefix = ascii2prefix (0, data);
		gateway_from = add_gateway (prefix, as, NULL);
		attr->gateway = gateway_from;
		Deref_Prefix (prefix);
	    }
	}

	/* type BGP/UPDATE */
	else if ((ret = checkstradvance (line, "TYPE"))) {
	    char *subtypestr;
	    char **cpp;
	    int i;

	    if ((subtypestr = strchr (ret, '/')) != NULL)
		*subtypestr++ = '\0';

	    cpp = S_MRT_MSG_TYPES;
	    for (i = 0; cpp[i]; i++) {
	        if (strcasecmp (cpp[i], ret) == 0)
			break;
	    }
	    type = (enum MRT_MSG_TYPES) i;

	    if (subtypestr) {
		char *subsubtypestr;

	        if ((subsubtypestr = strchr (subtypestr, '/')) != NULL)
		    *subsubtypestr++ = '\0';
		if ((cpp = S_MRT_MSG_SUBTYPES[type]) != NULL) {
		    for (i = 0; cpp[i]; i++) {
		        if (strcasecmp (cpp[i], subtypestr) == 0)
			    break;
		    }
		    subtype = i;
		}
		newtype = subtype;

		if (type == MSG_PROTOCOL_BGP ||
			type == MSG_PROTOCOL_BGP4PLUS ||
			type == MSG_PROTOCOL_BGP4PLUS_01) {
		    if (subtype == MSG_BGP_UPDATE) {
		        bgptype = BGP_UPDATE;
			newtype = BGP4MP_MESSAGE;
		    }
		    else if (subtype == MSG_BGP_KEEPALIVE) {
		        bgptype = BGP_KEEPALIVE;
			newtype = BGP4MP_MESSAGE;
		    }
		    else if (subtype == MSG_BGP_NOTIFY) {
		        bgptype = BGP_NOTIFY;
			newtype = BGP4MP_MESSAGE;
		    }
		    else if (subtype == MSG_BGP_OPEN) {
		        bgptype = BGP_OPEN;
			newtype = BGP4MP_MESSAGE;
		    }
		    else if (subtype == MSG_BGP_SYNC) {
			newtype = BGP4MP_SNAPSHOT;
		    }
		    else if (subtype == MSG_BGP_STATE_CHANGE) {
			newtype = BGP4MP_STATE_CHANGE;
		    }
		    else if (subtype == MSG_TABLE_DUMP) {
			newtype = BGP4MP_ENTRY;
		    }
		}
		else if (type == MSG_PROTOCOL_BGP4MP && (
			subtype == BGP4MP_MESSAGE || 
			subtype == BGP4MP_MESSAGE_OLD)) {
		    for (i = 0; sbgp_pdus[i]; i++) {
		        if (strcasecmp (sbgp_pdus[i], subsubtypestr) == 0) {
		    	    bgptype = i;
			    break;
			}
		    }
		}
	    }

	    if (type == MSG_PROTOCOL_BGP
		    || type == MSG_PROTOCOL_BGP4PLUS
		    || type == MSG_PROTOCOL_BGP4PLUS_01
		    || type == MSG_TABLE_DUMP
		    || type == MSG_PROTOCOL_BGP4MP
		    ) {
		/* OK */
	    }
	    else {
		trace (TR_ERROR, MRT->trace, 
		       "Unknown message type %s at line %d\n", ret, line_num);
		goto error;
	    }
	}

	else if ((ret = checkstradvance (line, "DATA"))) {
	    bp = bgp_packet;
	    have_data2++;
	}
	else if (newtype == BGP4MP_STATE_CHANGE &&
	         (ret = checkstradvance (line, "PEER"))) {
	    int as;
    	    char data[MAXLINE];
	    if (sscanf (ret, "%s AS%d", data, &as) >= 2 ||
	        sscanf (ret, "AS%d %s", &as, data) >= 2 /* obsolete */) {
		prefix_t *prefix = ascii2prefix (0, data);
		gateway_from = add_gateway (prefix, as, NULL);
		Deref_Prefix (prefix);
	    }
	}
	else if (newtype == BGP4MP_STATE_CHANGE &&
	         (ret = checkstradvance (line, "STATE"))) {
	    char *cp = strchr (ret, '/');
	    int i;

	    if (cp == NULL)
		goto error;
	    *cp++ = '\0';
	    for (i = 0; sbgp_states[i]; i++) {
		if (strcasecmp (sbgp_states[i], ret) == 0) {
		    state1 = i;
		}
	    }
	    for (i = 0; sbgp_states[i]; i++) {
		if (strcasecmp (sbgp_states[i], cp) == 0) {
		    state2 = i;
		}
	    }
	}
	else if ((newtype == BGP4MP_SNAPSHOT || newtype == BGP4MP_ENTRY) &&
	         (ret = checkstradvance (line, "VIEW"))) {
	    viewno = atoi (ret);
	}
	else if (newtype == BGP4MP_SNAPSHOT &&
	         (ret = checkstradvance (line, "FILE"))) {
	    if (filename)
		free (filename);
	    filename = strdup (ret);
	}
	else if (newtype == BGP4MP_ENTRY &&
	         (ret = checkstradvance (line, "PREFIX"))) {
	    if (route_prefix == NULL) {
	    	buffer_p = buffer;
		if (type == MSG_TABLE_DUMP) {
	    	    BGP_PUT_SHORT (viewno, buffer_p);
            	    BGP_PUT_SHORT (seq_num, buffer_p);
		}
	    }
	    else {
		buffer_p = bgp_table_dump_entry (buffer_p, end, type, subtype,
                      viewno, route_prefix, status, originated, attr);
	    }
	    route_prefix = ascii2prefix (0, ret);
	    bgp_deref_attr (attr);
	    attr = bgp_new_attr (PROTO_BGP);
	}
	else if (newtype == BGP4MP_ENTRY &&
	         (ret = checkstradvance (line, "SEQUENCE"))) {
	    seq_num = atoi (ret);
	}
	else if (newtype == BGP4MP_ENTRY &&
	        (ret = checkstradvance (line, "ORIGINATED"))) {
	    struct tm tm;
	    if (strptime (ret, "%D %T", &tm)) {
		time_t now;
		time (&now);
		tm.tm_isdst = localtime (&now)->tm_isdst;
		adjust_y2k (&tm);
		originated = mktime (&tm);
	    }
	}
	else if (newtype == BGP4MP_ENTRY &&
	         (ret = checkstradvance (line, "STATUS"))) {
	    sscanf (ret, "%li", &status);
	}
	else if (bgptype == BGP_OPEN &&
		(ret = checkstradvance (line, "VERSION"))) {
	    version = atoi (ret);
	}
	else if (bgptype == BGP_OPEN &&
		(ret = checkstradvance (line, "AS"))) {
	    as = atoi (ret);
	}
	else if (bgptype == BGP_OPEN &&
		(ret = checkstradvance (line, "HOLD_TIME"))) {
	    holdtime = atoi (ret);
	}
	else if (bgptype == BGP_OPEN &&
		(ret = checkstradvance (line, "ID"))) {
	    inet_pton (AF_INET, ret, &id);
	}
	else if (bgptype == BGP_OPEN &&
		(ret = checkstradvance (line, "OPT_PARM_LEN"))) {
	    optlen = atoi (ret);
	}
	else if (bgptype == BGP_NOTIFY &&
		(ret = checkstradvance (line, "CODE"))) {
	    char *cp;
	    code = atoi (ret);
	    if ((cp = strchr (ret, '/')) != NULL)
		subcode = atoi (cp + 1);
	}
	else if (bgptype == BGP_UPDATE &&
		(ret = checkstradvance (line, "ANNOUNCE"))) {
	    announce_flag = 1;
	    have_data++;
	}
	else if (bgptype == BGP_UPDATE &&
		(ret = checkstradvance (line, "WITHDRAW"))) {
	    announce_flag = 0;
	    have_data++;
	}
	else if ((bgptype == BGP_UPDATE || newtype == BGP4MP_ENTRY) &&
		(ok = bgp_scan_attr (line, attr, MRT->trace)) > 0) {
	    /* OK */
	}
	else if ((bgptype == BGP_UPDATE || newtype == BGP4MP_ENTRY) && ok < 0) {
	    trace (TR_ERROR, MRT->trace, 
	           "Invalid BGP attribute at line %d\n", line_num);
	    goto error;
	}
	else {
	    trace (TR_ERROR, MRT->trace, "Unrecognized line at %d\n", line_num);
	    goto error;
	}
    }

error:
    if (filename)
	free (filename);
    bgp_deref_attr (attr);
    LL_Destroy (ll_ann);
    LL_Destroy (ll_with);
    Delete_Buffer (stdbuf);
}
コード例 #5
0
ファイル: qif.c プロジェクト: deepfield/MRT
static int
qif_set_flow (srsvp_t *srsvp, srsvp_flow_t *flow, srsvp_leaf_t *leaf, int type)
{
    u_char msgbuf[1024];
    int ret;
    struct rt_msghdr *rtm = (struct rt_msghdr *) msgbuf;
    struct qos_msghdr *qosm = (struct qos_msghdr *) (rtm + 1);
    qos_rtflow_t *qosr = (qos_rtflow_t *) (qosm + 1);
    sockunion_t *su;
    prefix_t *gateway;

    memset (rtm, 0, sizeof (*rtm));
    memset (qosm, 0, sizeof (*qosm));

    assert (type == RTM_FLOW_ADD || type == RTM_FLOW_DEL);
    rtm->rtm_type = type;
    rtm->rtm_msglen = sizeof (*rtm) + sizeof (*qosm);

    assert (flow); assert (leaf);
    qosm->qifi = leaf->neighbor->vif->interface->index;
    if (type == RTM_FLOW_ADD) {
        if (flow->upstream)
            qosm->parent = flow->upstream->vif->interface->index;
        else
            qosm->parent = qosm->qifi; /* XXX I'm not sure */
        memcpy (&qosm->qos, leaf->req_qos, sizeof (qosm->qos));
        qosm->flags = (QOS_FLOW_QOS | QOS_FLOW_ROUTE);
    }

    assert (flow->sender);
    assert (flow->destin);
    assert (flow->sender->family == flow->destin->family);
#ifdef HAVE_IPV6
    if (flow->upstream->prefix->family == AF_INET6) {
        memset (qosr, 0, sizeof (qosr->fin6));
	qosr->fin6.family = AF_INET6;
	qosr->fin6.len = sizeof (qosr->fin6);
	qosr->fin6.proto = flow->proto;
	memcpy (&qosr->fin6.src, prefix_tochar (flow->sender), 16);
	memcpy (&qosr->fin6.dest, prefix_tochar (leaf->destin), 16);
	qosr->fin6.sport = htons (flow->sport);
	qosr->fin6.dport = htons (flow->dport);
    	rtm->rtm_msglen += sizeof (qosr->fin6);
        su = (sockunion_t *)(((u_char *) qosr) + sizeof (qosr->fin6));
    }
    else
#endif /* HAVE_IPV6 */
    {
        memset (qosr, 0, sizeof (qosr->fin));
	qosr->fin.family = AF_INET;
	qosr->fin.len = sizeof (qosr->fin);
	qosr->fin.proto = flow->proto;
	memcpy (&qosr->fin.src, prefix_tochar (flow->sender), 4);
	memcpy (&qosr->fin.dest, prefix_tochar (flow->destin), 4);
	qosr->fin.sport = htons (flow->sport);
	qosr->fin.dport = htons (flow->dport);
    	rtm->rtm_msglen += sizeof (qosr->fin);
        su = (sockunion_t *)(((u_char *) qosr) + sizeof (qosr->fin));
    }

    gateway = leaf->neighbor->prefix;
    assert (gateway);
#ifdef HAVE_IPV6
    if (gateway->family == AF_INET6) {
        memset (su, 0, sizeof (su->sin6));
	su->sin6.sin6_family = AF_INET6;
	su->sin6.sin6_len = sizeof (su->sin6);
	memcpy (&su->sin6.sin6_addr, prefix_tochar (gateway), 16);
    	rtm->rtm_msglen += sizeof (su->sin6);
    }
    else
#endif /* HAVE_IPV6 */
    {
        memset (su, 0, sizeof (su->sin));
        su->sin.sin_family = AF_INET;
	su->sin.sin_len = sizeof (su->sin);
	memcpy (&su->sin.sin_addr, prefix_tochar (gateway), 4);
    	rtm->rtm_msglen += sizeof (su->sin);
    }
    qosm->flags |= QOS_FLOW_GATEWAY;

    if ((ret = qif_sendmsg (rtm)) < 0) {
        trace (TR_ERROR, MRT->trace, "QIF qif_set_flow (%m)\n");
    }
    else {
        trace (TR_INFO, MRT->trace, "QIF flow %a port %d index %d %s\n", 
	    flow->destin, flow->dport, qosm->qifi,
	    (type == RTM_FLOW_ADD)? "created": "removed");
    }
    return (ret);
}