mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-28 21:20:48 +00:00
Update Traffic Engineering Support for OSPFD
NOTE: I am squashing several commits together because they do not independently compile and we need this ability to do any type of sane testing on the patches. Since this series builds together I am doing this. -DBS This new structure is the basis to get new link parameters for Traffic Engineering from Zebra/interface layer to OSPFD and ISISD for the support of Traffic Engineering * lib/if.[c,h]: link parameters struture and get/set functions * lib/command.[c,h]: creation of a new link-node * lib/zclient.[c,h]: modification to the ZBUS message to convey the link parameters structure * lib/zebra.h: New ZBUS message Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Add support for IEEE 754 format * lib/stream.[c,h]: Add stream_get{f,d} and stream_put{f,d}) demux and muxers to safely convert between big-endian IEEE-754 single and double binary format, as used in IETF RFCs, and C99. Implementation depends on host using __STDC_IEC_559__, which should be everything we care about. Should correctly error out otherwise. * lib/network.[c,h]: Add ntohf and htonf converter * lib/memtypes.c: Add new memeory type for Traffic Engineering support Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Add link parameters support to Zebra * zebra/interface.c: - Add new link-params CLI commands - Add new functions to set/get link parameters for interface * zebra/redistribute.[c,h]: Add new function to propagate link parameters to routing daemon (essentially OSPFD and ISISD) for Traffic Engineering. * zebra/redistribute_null.c: Add new function zebra_interface_parameters_update() * zebra/zserv.[c,h]: Add new functions to send link parameters Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Add support of new link-params CLI to vtysh In vtysh_config.c/vtysh_config_parse_line(), it is not possible to continue to use the ordered version for adding line i.e. config_add_line_uniq() to print Interface CLI commands as it completely break the new LINK_PARAMS_NODE. Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Update Traffic Engineering support for OSPFD These patches update original code to RFC3630 (OSPF-TE) and add support of RFC5392 (Inter-AS v2) & RFC7471 (TE metric extensions) and partial support of RFC6827 (ASON - GMPLS). * ospfd/ospf_dump.[c,h]: Add new dump functions for Traffic Engineering * ospfd/ospf_opaque.[c,h]: Add new TLV code points for RFC5392 * ospfd/ospf_packet.c: Update checking of OSPF_OPTION * ospfd/ospf_vty.[c,h]: Update ospf_str2area_id * ospfd/ospf_zebra.c: Add new function ospf_interface_link_params() to get Link Parameters information from the interface to populate Traffic Engineering metrics * ospfd/ospfd.[c,h]: Update OSPF_OPTION flags (T -> MT and new DN) * ospfd/ospf_te.[c,h]: Major modifications to update the code to new link parameters structure and new RFCs Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> tmp
This commit is contained in:
parent
8ccc7e802b
commit
16f1b9ee29
@ -2537,8 +2537,12 @@ node_parent ( enum node_type node )
|
||||
case KEYCHAIN_KEY_NODE:
|
||||
ret = KEYCHAIN_NODE;
|
||||
break;
|
||||
case LINK_PARAMS_NODE:
|
||||
ret = INTERFACE_NODE;
|
||||
break;
|
||||
default:
|
||||
ret = CONFIG_NODE;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -2926,6 +2930,9 @@ DEFUN (config_exit,
|
||||
case KEYCHAIN_KEY_NODE:
|
||||
vty->node = KEYCHAIN_NODE;
|
||||
break;
|
||||
case LINK_PARAMS_NODE:
|
||||
vty->node = INTERFACE_NODE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -2975,6 +2982,7 @@ DEFUN (config_end,
|
||||
case MASC_NODE:
|
||||
case PIM_NODE:
|
||||
case VTY_NODE:
|
||||
case LINK_PARAMS_NODE:
|
||||
vty_config_unlock (vty);
|
||||
vty->node = ENABLE_NODE;
|
||||
break;
|
||||
|
@ -108,6 +108,7 @@ enum node_type
|
||||
FORWARDING_NODE, /* IP forwarding node. */
|
||||
PROTOCOL_NODE, /* protocol filtering node */
|
||||
VTY_NODE, /* Vty node. */
|
||||
LINK_PARAMS_NODE, /* Link-parameters node */
|
||||
};
|
||||
|
||||
/* Node which has some commands and prompt string and configuration
|
||||
@ -516,6 +517,10 @@ struct cmd_token
|
||||
#define AREA_TAG_STR "[area tag]\n"
|
||||
#define COMMUNITY_AANN_STR "Community number where AA and NN are <0-65535>\n"
|
||||
#define COMMUNITY_VAL_STR "Community number in AA:NN format (where AA and NN are <0-65535>) or local-AS|no-advertise|no-export|internet or additive\n"
|
||||
#define MPLS_TE_STR "MPLS-TE specific commands\n"
|
||||
#define LINK_PARAMS_STR "Configure interface link parameters\n"
|
||||
#define OSPF_RI_STR "OSPF Router Information specific commands\n"
|
||||
#define PCE_STR "PCE Router Information specific commands\n"
|
||||
|
||||
#define CONF_BACKUP_EXT ".sav"
|
||||
|
||||
|
44
lib/if.c
44
lib/if.c
@ -205,6 +205,8 @@ if_delete (struct interface *ifp)
|
||||
list_free (ifp->connected);
|
||||
list_free (ifp->nbr_connected);
|
||||
|
||||
if_link_params_free (ifp);
|
||||
|
||||
XFREE (MTYPE_IF, ifp);
|
||||
}
|
||||
|
||||
@ -1364,3 +1366,45 @@ if_link_type_str (enum zebra_link_type llt)
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct if_link_params *
|
||||
if_link_params_get (struct interface *ifp)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (ifp->link_params != NULL)
|
||||
return ifp->link_params;
|
||||
|
||||
struct if_link_params *iflp = XCALLOC(MTYPE_IF_LINK_PARAMS,
|
||||
sizeof (struct if_link_params));
|
||||
if (iflp == NULL) return NULL;
|
||||
|
||||
/* Set TE metric == standard metric */
|
||||
iflp->te_metric = ifp->metric;
|
||||
|
||||
/* Compute default bandwidth based on interface */
|
||||
int bw = (float)((ifp->bandwidth ? ifp->bandwidth : DEFAULT_BANDWIDTH)
|
||||
* TE_KILO_BIT / TE_BYTE);
|
||||
|
||||
/* Set Max, Reservable and Unreserved Bandwidth */
|
||||
iflp->max_bw = bw;
|
||||
iflp->max_rsv_bw = bw;
|
||||
for (i = 0; i < MAX_CLASS_TYPE; i++)
|
||||
iflp->unrsv_bw[i] = bw;
|
||||
|
||||
/* Update Link parameters status */
|
||||
iflp->lp_status = LP_TE | LP_MAX_BW | LP_MAX_RSV_BW | LP_UNRSV_BW;
|
||||
|
||||
/* Finally attach newly created Link Parameters */
|
||||
ifp->link_params = iflp;
|
||||
|
||||
return iflp;
|
||||
}
|
||||
|
||||
void
|
||||
if_link_params_free (struct interface *ifp)
|
||||
{
|
||||
if (ifp->link_params == NULL) return;
|
||||
XFREE(MTYPE_IF_LINK_PARAMS, ifp->link_params);
|
||||
ifp->link_params = NULL;
|
||||
}
|
||||
|
64
lib/if.h
64
lib/if.h
@ -131,6 +131,63 @@ struct if_stats
|
||||
};
|
||||
#endif /* HAVE_PROC_NET_DEV */
|
||||
|
||||
/* Here are "non-official" architectural constants. */
|
||||
#define TE_EXT_MASK 0x0FFFFFFF
|
||||
#define TE_EXT_ANORMAL 0x80000000
|
||||
#define LOSS_PRECISION 0.000003
|
||||
#define TE_KILO_BIT 1000
|
||||
#define TE_BYTE 8
|
||||
#define DEFAULT_BANDWIDTH 10000
|
||||
#define MAX_CLASS_TYPE 8
|
||||
#define MAX_PKT_LOSS 50.331642
|
||||
|
||||
/* Link Parameters Status: 0: unset, 1: set, */
|
||||
#define LP_UNSET 0x0000
|
||||
#define LP_TE 0x0001
|
||||
#define LP_MAX_BW 0x0002
|
||||
#define LP_MAX_RSV_BW 0x0004
|
||||
#define LP_UNRSV_BW 0x0008
|
||||
#define LP_ADM_GRP 0x0010
|
||||
#define LP_RMT_AS 0x0020
|
||||
#define LP_DELAY 0x0040
|
||||
#define LP_MM_DELAY 0x0080
|
||||
#define LP_DELAY_VAR 0x0100
|
||||
#define LP_PKT_LOSS 0x0200
|
||||
#define LP_RES_BW 0x0400
|
||||
#define LP_AVA_BW 0x0800
|
||||
#define LP_USE_BW 0x1000
|
||||
|
||||
#define IS_PARAM_UNSET(lp, st) !(lp->lp_status & st)
|
||||
#define IS_PARAM_SET(lp, st) (lp->lp_status & st)
|
||||
#define IS_LINK_PARAMS_SET(lp) (lp->lp_status != LP_UNSET)
|
||||
|
||||
#define SET_PARAM(lp, st) (lp->lp_status) |= (st)
|
||||
#define UNSET_PARAM(lp, st) (lp->lp_status) &= ~(st)
|
||||
#define RESET_LINK_PARAM(lp) (lp->lp_status = LP_UNSET)
|
||||
|
||||
/* Link Parameters for Traffic Engineering */
|
||||
struct if_link_params {
|
||||
u_int32_t lp_status; /* Status of Link Parameters: */
|
||||
u_int32_t te_metric; /* Traffic Engineering metric */
|
||||
float max_bw; /* Maximum Bandwidth */
|
||||
float max_rsv_bw; /* Maximum Reservable Bandwidth */
|
||||
float unrsv_bw[MAX_CLASS_TYPE]; /* Unreserved Bandwidth per Class Type (8) */
|
||||
u_int32_t admin_grp; /* Administrative group */
|
||||
u_int32_t rmt_as; /* Remote AS number */
|
||||
struct in_addr rmt_ip; /* Remote IP address */
|
||||
u_int32_t av_delay; /* Link Average Delay */
|
||||
u_int32_t min_delay; /* Link Min Delay */
|
||||
u_int32_t max_delay; /* Link Max Delay */
|
||||
u_int32_t delay_var; /* Link Delay Variation */
|
||||
float pkt_loss; /* Link Packet Loss */
|
||||
float res_bw; /* Residual Bandwidth */
|
||||
float ava_bw; /* Available Bandwidth */
|
||||
float use_bw; /* Utilized Bandwidth */
|
||||
};
|
||||
|
||||
#define INTERFACE_LINK_PARAMS_SIZE sizeof(struct if_link_params)
|
||||
#define HAS_LINK_PARAMS(ifp) ((ifp)->link_params != NULL)
|
||||
|
||||
/* Interface structure */
|
||||
struct interface
|
||||
{
|
||||
@ -174,6 +231,9 @@ struct interface
|
||||
/* interface bandwidth, kbits */
|
||||
unsigned int bandwidth;
|
||||
|
||||
/* Link parameters for Traffic Engineering */
|
||||
struct if_link_params *link_params;
|
||||
|
||||
/* description of the interface. */
|
||||
char *desc;
|
||||
|
||||
@ -418,6 +478,10 @@ extern ifindex_t if_nametoindex (const char *);
|
||||
extern char *if_indextoname (ifindex_t, char *);
|
||||
#endif
|
||||
|
||||
/* link parameters */
|
||||
struct if_link_params *if_link_params_get (struct interface *);
|
||||
void if_link_params_free (struct interface *);
|
||||
|
||||
/* Exported variables. */
|
||||
extern struct cmd_element interface_desc_cmd;
|
||||
extern struct cmd_element no_interface_desc_cmd;
|
||||
|
@ -77,6 +77,7 @@ struct memory_list memory_list_lib[] =
|
||||
{ MTYPE_VRF, "VRF" },
|
||||
{ MTYPE_VRF_NAME, "VRF name" },
|
||||
{ MTYPE_VRF_BITMAP, "VRF bit-map" },
|
||||
{ MTYPE_IF_LINK_PARAMS, "Informational Link Parameters" },
|
||||
{ -1, NULL },
|
||||
};
|
||||
|
||||
@ -228,6 +229,8 @@ struct memory_list memory_list_ospf[] =
|
||||
{ MTYPE_OSPF_IF_INFO, "OSPF if info" },
|
||||
{ MTYPE_OSPF_IF_PARAMS, "OSPF if params" },
|
||||
{ MTYPE_OSPF_MESSAGE, "OSPF message" },
|
||||
{ MTYPE_OSPF_MPLS_TE, "OSPF MPLS parameters" },
|
||||
{ MTYPE_OSPF_PCE_PARAMS, "OSPF PCE parameters" },
|
||||
{ -1, NULL },
|
||||
};
|
||||
|
||||
@ -269,6 +272,7 @@ struct memory_list memory_list_isis[] =
|
||||
{ MTYPE_ISIS_NEXTHOP6, "ISIS nexthop6" },
|
||||
{ MTYPE_ISIS_DICT, "ISIS dictionary" },
|
||||
{ MTYPE_ISIS_DICT_NODE, "ISIS dictionary node" },
|
||||
{ MTYPE_ISIS_MPLS_TE, "ISIS MPLS_TE parameters" },
|
||||
{ -1, NULL },
|
||||
};
|
||||
|
||||
|
@ -93,3 +93,21 @@ set_nonblocking(int fd)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
float
|
||||
htonf (float host)
|
||||
{
|
||||
u_int32_t lu1, lu2;
|
||||
float convert;
|
||||
|
||||
memcpy (&lu1, &host, sizeof (u_int32_t));
|
||||
lu2 = htonl (lu1);
|
||||
memcpy (&convert, &lu2, sizeof (u_int32_t));
|
||||
return convert;
|
||||
}
|
||||
|
||||
float
|
||||
ntohf (float net)
|
||||
{
|
||||
return htonf (net);
|
||||
}
|
||||
|
@ -37,4 +37,7 @@ extern int set_nonblocking(int fd);
|
||||
#define ERRNO_IO_RETRY(EN) \
|
||||
(((EN) == EAGAIN) || ((EN) == EWOULDBLOCK) || ((EN) == EINTR))
|
||||
|
||||
extern float htonf (float);
|
||||
extern float ntohf (float);
|
||||
|
||||
#endif /* _ZEBRA_NETWORK_H */
|
||||
|
44
lib/stream.c
44
lib/stream.c
@ -543,6 +543,28 @@ stream_get_ipv4 (struct stream *s)
|
||||
return l;
|
||||
}
|
||||
|
||||
float
|
||||
stream_getf (struct stream *s)
|
||||
{
|
||||
union {
|
||||
float r;
|
||||
uint32_t d;
|
||||
} u;
|
||||
u.d = stream_getl (s);
|
||||
return u.r;
|
||||
}
|
||||
|
||||
double
|
||||
stream_getd (struct stream *s)
|
||||
{
|
||||
union {
|
||||
double r;
|
||||
uint64_t d;
|
||||
} u;
|
||||
u.d = stream_getq (s);
|
||||
return u.r;
|
||||
}
|
||||
|
||||
/* Copy to source to stream.
|
||||
*
|
||||
* XXX: This uses CHECK_SIZE and hence has funny semantics -> Size will wrap
|
||||
@ -670,6 +692,28 @@ stream_putq (struct stream *s, uint64_t q)
|
||||
return 8;
|
||||
}
|
||||
|
||||
int
|
||||
stream_putf (struct stream *s, float f)
|
||||
{
|
||||
union {
|
||||
float i;
|
||||
uint32_t o;
|
||||
} u;
|
||||
u.i = f;
|
||||
return stream_putl (s, u.o);
|
||||
}
|
||||
|
||||
int
|
||||
stream_putd (struct stream *s, double d)
|
||||
{
|
||||
union {
|
||||
double i;
|
||||
uint64_t o;
|
||||
} u;
|
||||
u.i = d;
|
||||
return stream_putq (s, u.o);
|
||||
}
|
||||
|
||||
int
|
||||
stream_putc_at (struct stream *s, size_t putp, u_char c)
|
||||
{
|
||||
|
@ -196,6 +196,12 @@ extern uint64_t stream_getq (struct stream *);
|
||||
extern uint64_t stream_getq_from (struct stream *, size_t);
|
||||
extern u_int32_t stream_get_ipv4 (struct stream *);
|
||||
|
||||
/* IEEE-754 floats */
|
||||
extern float stream_getf (struct stream *);
|
||||
extern double stream_getd (struct stream *);
|
||||
extern int stream_putf (struct stream *, float);
|
||||
extern int stream_putd (struct stream *, double);
|
||||
|
||||
#undef stream_read
|
||||
#undef stream_write
|
||||
|
||||
|
172
lib/zclient.c
172
lib/zclient.c
@ -960,8 +960,6 @@ zebra_router_id_update_read (struct stream *s, struct prefix *rid)
|
||||
* ZEBRA_INTERFACE_DELETE from zebra to the client is:
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+
|
||||
* | type |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | ifname |
|
||||
* | |
|
||||
@ -971,6 +969,8 @@ zebra_router_id_update_read (struct stream *s, struct prefix *rid)
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | ifindex |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | status |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | if_flags |
|
||||
* | |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
@ -982,7 +982,17 @@ zebra_router_id_update_read (struct stream *s, struct prefix *rid)
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | bandwidth |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | sockaddr_dl |
|
||||
* | Link Layer Type |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Harware Address Length |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Hardware Address if HW lenght different from 0 |
|
||||
* | ... max INTERFACE_HWADDR_MAX |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Link_params? | Whether a link-params follows: 1 or 0.
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Link_params 0 or 1 INTERFACE_LINK_PARAMS_SIZE sized |
|
||||
* | .... (struct if_link_params). |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
@ -1071,6 +1081,137 @@ zebra_interface_state_read (struct stream *s, vrf_id_t vrf_id)
|
||||
return ifp;
|
||||
}
|
||||
|
||||
static void
|
||||
link_params_set_value(struct stream *s, struct if_link_params *iflp)
|
||||
{
|
||||
|
||||
if (iflp == NULL)
|
||||
return;
|
||||
|
||||
iflp->lp_status = stream_getl (s);
|
||||
iflp->te_metric = stream_getl (s);
|
||||
iflp->max_bw = stream_getf (s);
|
||||
iflp->max_rsv_bw = stream_getf (s);
|
||||
uint32_t bwclassnum = stream_getl (s);
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < bwclassnum && i < MAX_CLASS_TYPE; i++)
|
||||
iflp->unrsv_bw[i] = stream_getf (s);
|
||||
if (i < bwclassnum)
|
||||
zlog_err ("%s: received %d > %d (MAX_CLASS_TYPE) bw entries"
|
||||
" - outdated library?",
|
||||
__func__, bwclassnum, MAX_CLASS_TYPE);
|
||||
}
|
||||
iflp->admin_grp = stream_getl (s);
|
||||
iflp->rmt_as = stream_getl (s);
|
||||
iflp->rmt_ip.s_addr = stream_get_ipv4 (s);
|
||||
|
||||
iflp->av_delay = stream_getl (s);
|
||||
iflp->min_delay = stream_getl (s);
|
||||
iflp->max_delay = stream_getl (s);
|
||||
iflp->delay_var = stream_getl (s);
|
||||
|
||||
iflp->pkt_loss = stream_getf (s);
|
||||
iflp->res_bw = stream_getf (s);
|
||||
iflp->ava_bw = stream_getf (s);
|
||||
iflp->use_bw = stream_getf (s);
|
||||
}
|
||||
|
||||
struct interface *
|
||||
zebra_interface_link_params_read (struct stream *s)
|
||||
{
|
||||
struct if_link_params *iflp;
|
||||
uint32_t ifindex = stream_getl (s);
|
||||
|
||||
struct interface *ifp = if_lookup_by_index (ifindex);
|
||||
|
||||
if (ifp == NULL || s == NULL)
|
||||
{
|
||||
zlog_err ("%s: unknown ifindex %u, shouldn't happen",
|
||||
__func__, ifindex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((iflp = if_link_params_get (ifp)) == NULL)
|
||||
return NULL;
|
||||
|
||||
link_params_set_value(s, iflp);
|
||||
|
||||
return ifp;
|
||||
}
|
||||
|
||||
void
|
||||
zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
|
||||
{
|
||||
u_char link_params_status = 0;
|
||||
|
||||
/* Read interface's index. */
|
||||
ifp->ifindex = stream_getl (s);
|
||||
ifp->status = stream_getc (s);
|
||||
|
||||
/* Read interface's value. */
|
||||
ifp->flags = stream_getq (s);
|
||||
ifp->ptm_enable = stream_getc (s);
|
||||
ifp->ptm_status = stream_getc (s);
|
||||
ifp->metric = stream_getl (s);
|
||||
ifp->mtu = stream_getl (s);
|
||||
ifp->mtu6 = stream_getl (s);
|
||||
ifp->bandwidth = stream_getl (s);
|
||||
ifp->ll_type = stream_getl (s);
|
||||
ifp->hw_addr_len = stream_getl (s);
|
||||
if (ifp->hw_addr_len)
|
||||
stream_get (ifp->hw_addr, s, MIN(ifp->hw_addr_len, INTERFACE_HWADDR_MAX));
|
||||
|
||||
/* Read Traffic Engineering status */
|
||||
link_params_status = stream_getc (s);
|
||||
/* Then, Traffic Engineering parameters if any */
|
||||
if (link_params_status)
|
||||
{
|
||||
struct if_link_params *iflp = if_link_params_get (ifp);
|
||||
link_params_set_value(s, iflp);
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
zebra_interface_link_params_write (struct stream *s, struct interface *ifp)
|
||||
{
|
||||
size_t w;
|
||||
struct if_link_params *iflp;
|
||||
int i;
|
||||
|
||||
if (s == NULL || ifp == NULL || ifp->link_params == NULL)
|
||||
return 0;
|
||||
|
||||
iflp = ifp->link_params;
|
||||
w = 0;
|
||||
|
||||
w += stream_putl (s, iflp->lp_status);
|
||||
|
||||
w += stream_putl (s, iflp->te_metric);
|
||||
w += stream_putf (s, iflp->max_bw);
|
||||
w += stream_putf (s, iflp->max_rsv_bw);
|
||||
|
||||
w += stream_putl (s, MAX_CLASS_TYPE);
|
||||
for (i = 0; i < MAX_CLASS_TYPE; i++)
|
||||
w += stream_putf (s, iflp->unrsv_bw[i]);
|
||||
|
||||
w += stream_putl (s, iflp->admin_grp);
|
||||
w += stream_putl (s, iflp->rmt_as);
|
||||
w += stream_put_in_addr (s, &iflp->rmt_ip);
|
||||
|
||||
w += stream_putl (s, iflp->av_delay);
|
||||
w += stream_putl (s, iflp->min_delay);
|
||||
w += stream_putl (s, iflp->max_delay);
|
||||
w += stream_putl (s, iflp->delay_var);
|
||||
|
||||
w += stream_putf (s, iflp->pkt_loss);
|
||||
w += stream_putf (s, iflp->res_bw);
|
||||
w += stream_putf (s, iflp->ava_bw);
|
||||
w += stream_putf (s, iflp->use_bw);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
/*
|
||||
* format of message for address additon is:
|
||||
* 0
|
||||
@ -1100,30 +1241,8 @@ zebra_interface_state_read (struct stream *s, vrf_id_t vrf_id)
|
||||
* : :
|
||||
* | |
|
||||
* +-+-+-+-+-+-+-+-+
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
|
||||
{
|
||||
/* Read interface's index. */
|
||||
ifp->ifindex = stream_getl (s);
|
||||
ifp->status = stream_getc (s);
|
||||
|
||||
/* Read interface's value. */
|
||||
ifp->flags = stream_getq (s);
|
||||
ifp->ptm_enable = stream_getc (s);
|
||||
ifp->ptm_status = stream_getc (s);
|
||||
ifp->metric = stream_getl (s);
|
||||
ifp->mtu = stream_getl (s);
|
||||
ifp->mtu6 = stream_getl (s);
|
||||
ifp->bandwidth = stream_getl (s);
|
||||
ifp->ll_type = stream_getl (s);
|
||||
ifp->hw_addr_len = stream_getl (s);
|
||||
if (ifp->hw_addr_len)
|
||||
stream_get (ifp->hw_addr, s, MIN(ifp->hw_addr_len, INTERFACE_HWADDR_MAX));
|
||||
}
|
||||
|
||||
static int
|
||||
memconstant(const void *s, int c, size_t n)
|
||||
{
|
||||
@ -1509,6 +1628,9 @@ zclient_read (struct thread *thread)
|
||||
case ZEBRA_REDISTRIBUTE_IPV6_DEL:
|
||||
if (zclient->redistribute_route_ipv6_del)
|
||||
(*zclient->redistribute_route_ipv6_del) (command, zclient, length, vrf_id);
|
||||
case ZEBRA_INTERFACE_LINK_PARAMS:
|
||||
if (zclient->interface_link_params)
|
||||
(*zclient->interface_link_params) (command, zclient, length);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -93,6 +93,7 @@ struct zclient
|
||||
int (*interface_down) (int, struct zclient *, uint16_t, vrf_id_t);
|
||||
int (*interface_address_add) (int, struct zclient *, uint16_t, vrf_id_t);
|
||||
int (*interface_address_delete) (int, struct zclient *, uint16_t, vrf_id_t);
|
||||
int (*interface_link_params) (int, struct zclient *, uint16_t);
|
||||
int (*interface_bfd_dest_update) (int, struct zclient *, uint16_t, vrf_id_t);
|
||||
int (*interface_nbr_address_add) (int, struct zclient *, uint16_t, vrf_id_t);
|
||||
int (*interface_nbr_address_delete) (int, struct zclient *, uint16_t, vrf_id_t);
|
||||
@ -214,6 +215,9 @@ extern void zebra_router_id_update_read (struct stream *s, struct prefix *rid);
|
||||
extern int zapi_ipv4_route (u_char, struct zclient *, struct prefix_ipv4 *,
|
||||
struct zapi_ipv4 *);
|
||||
|
||||
extern struct interface *zebra_interface_link_params_read (struct stream *);
|
||||
extern size_t zebra_interface_link_params_write (struct stream *,
|
||||
struct interface *);
|
||||
#ifdef HAVE_IPV6
|
||||
/* IPv6 prefix add and delete function prototype. */
|
||||
|
||||
|
@ -445,7 +445,8 @@ struct in_pktinfo
|
||||
#define ZEBRA_INTERFACE_ENABLE_RADV 47
|
||||
#define ZEBRA_INTERFACE_DISABLE_RADV 48
|
||||
#define ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB 49
|
||||
#define ZEBRA_MESSAGE_MAX 50
|
||||
#define ZEBRA_INTERFACE_LINK_PARAMS 50
|
||||
#define ZEBRA_MESSAGE_MAX 51
|
||||
|
||||
/* Marker value used in new Zserv, in the byte location corresponding
|
||||
* the command value in the old zserv header. To allow old and new
|
||||
|
@ -133,6 +133,7 @@ unsigned long conf_debug_ospf_nsm = 0;
|
||||
unsigned long conf_debug_ospf_lsa = 0;
|
||||
unsigned long conf_debug_ospf_zebra = 0;
|
||||
unsigned long conf_debug_ospf_nssa = 0;
|
||||
unsigned long conf_debug_ospf_te = 0;
|
||||
|
||||
/* Enable debug option variables -- valid only session. */
|
||||
unsigned long term_debug_ospf_packet[5] = {0, 0, 0, 0, 0};
|
||||
@ -142,7 +143,7 @@ unsigned long term_debug_ospf_nsm = 0;
|
||||
unsigned long term_debug_ospf_lsa = 0;
|
||||
unsigned long term_debug_ospf_zebra = 0;
|
||||
unsigned long term_debug_ospf_nssa = 0;
|
||||
|
||||
unsigned long term_debug_ospf_te = 0;
|
||||
|
||||
|
||||
const char *
|
||||
@ -328,13 +329,14 @@ ospf_options_dump (u_char options)
|
||||
{
|
||||
static char buf[OSPF_OPTION_STR_MAXLEN];
|
||||
|
||||
snprintf (buf, OSPF_OPTION_STR_MAXLEN, "*|%s|%s|%s|%s|%s|%s|*",
|
||||
snprintf (buf, OSPF_OPTION_STR_MAXLEN, "*|%s|%s|%s|%s|%s|%s|%s",
|
||||
(options & OSPF_OPTION_O) ? "O" : "-",
|
||||
(options & OSPF_OPTION_DC) ? "DC" : "-",
|
||||
(options & OSPF_OPTION_EA) ? "EA" : "-",
|
||||
(options & OSPF_OPTION_NP) ? "N/P" : "-",
|
||||
(options & OSPF_OPTION_MC) ? "MC" : "-",
|
||||
(options & OSPF_OPTION_E) ? "E" : "-");
|
||||
(options & OSPF_OPTION_E) ? "E" : "-",
|
||||
(options & OSPF_OPTION_MT) ? "M/T" : "-");
|
||||
|
||||
return buf;
|
||||
}
|
||||
@ -1920,6 +1922,33 @@ DEFUN (no_debug_ospf_instance_nssa,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (debug_ospf_te,
|
||||
debug_ospf_te_cmd,
|
||||
"debug ospf te",
|
||||
DEBUG_STR
|
||||
OSPF_STR
|
||||
"OSPF-TE information\n")
|
||||
{
|
||||
if (vty->node == CONFIG_NODE)
|
||||
CONF_DEBUG_ON (te, TE);
|
||||
TERM_DEBUG_ON (te, TE);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (no_debug_ospf_te,
|
||||
no_debug_ospf_te_cmd,
|
||||
"no debug ospf te",
|
||||
NO_STR
|
||||
DEBUG_STR
|
||||
OSPF_STR
|
||||
"OSPF-TE information\n")
|
||||
{
|
||||
if (vty->node == CONFIG_NODE)
|
||||
CONF_DEBUG_OFF (te, TE);
|
||||
TERM_DEBUG_OFF (te, TE);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (no_debug_ospf,
|
||||
no_debug_ospf_cmd,
|
||||
"no debug ospf",
|
||||
@ -2270,6 +2299,7 @@ debug_init ()
|
||||
install_element (ENABLE_NODE, &debug_ospf_zebra_cmd);
|
||||
install_element (ENABLE_NODE, &debug_ospf_event_cmd);
|
||||
install_element (ENABLE_NODE, &debug_ospf_nssa_cmd);
|
||||
install_element (ENABLE_NODE, &debug_ospf_te_cmd);
|
||||
install_element (ENABLE_NODE, &no_debug_ospf_packet_send_recv_detail_cmd);
|
||||
install_element (ENABLE_NODE, &no_debug_ospf_packet_send_recv_cmd);
|
||||
install_element (ENABLE_NODE, &no_debug_ospf_packet_all_cmd);
|
||||
@ -2283,6 +2313,7 @@ debug_init ()
|
||||
install_element (ENABLE_NODE, &no_debug_ospf_zebra_cmd);
|
||||
install_element (ENABLE_NODE, &no_debug_ospf_event_cmd);
|
||||
install_element (ENABLE_NODE, &no_debug_ospf_nssa_cmd);
|
||||
install_element (ENABLE_NODE, &no_debug_ospf_te_cmd);
|
||||
|
||||
install_element (ENABLE_NODE, &show_debugging_ospf_instance_cmd);
|
||||
install_element (ENABLE_NODE, &debug_ospf_instance_packet_send_recv_detail_cmd);
|
||||
@ -2326,6 +2357,7 @@ debug_init ()
|
||||
install_element (CONFIG_NODE, &debug_ospf_zebra_cmd);
|
||||
install_element (CONFIG_NODE, &debug_ospf_event_cmd);
|
||||
install_element (CONFIG_NODE, &debug_ospf_nssa_cmd);
|
||||
install_element (CONFIG_NODE, &debug_ospf_te_cmd);
|
||||
install_element (CONFIG_NODE, &no_debug_ospf_packet_send_recv_detail_cmd);
|
||||
install_element (CONFIG_NODE, &no_debug_ospf_packet_send_recv_cmd);
|
||||
install_element (CONFIG_NODE, &no_debug_ospf_packet_all_cmd);
|
||||
@ -2339,6 +2371,7 @@ debug_init ()
|
||||
install_element (CONFIG_NODE, &no_debug_ospf_zebra_cmd);
|
||||
install_element (CONFIG_NODE, &no_debug_ospf_event_cmd);
|
||||
install_element (CONFIG_NODE, &no_debug_ospf_nssa_cmd);
|
||||
install_element (CONFIG_NODE, &no_debug_ospf_te_cmd);
|
||||
|
||||
install_element (CONFIG_NODE, &debug_ospf_instance_packet_send_recv_detail_cmd);
|
||||
install_element (CONFIG_NODE, &debug_ospf_instance_packet_send_recv_cmd);
|
||||
|
@ -57,6 +57,7 @@
|
||||
|
||||
#define OSPF_DEBUG_EVENT 0x01
|
||||
#define OSPF_DEBUG_NSSA 0x02
|
||||
#define OSPF_DEBUG_TE 0x04
|
||||
|
||||
/* Macro for setting debug option. */
|
||||
#define CONF_DEBUG_PACKET_ON(a, b) conf_debug_ospf_packet[a] |= (b)
|
||||
@ -98,6 +99,8 @@
|
||||
|
||||
#define IS_DEBUG_OSPF_NSSA IS_DEBUG_OSPF(nssa,NSSA)
|
||||
|
||||
#define IS_DEBUG_OSPF_TE IS_DEBUG_OSPF(te,TE)
|
||||
|
||||
#define IS_CONF_DEBUG_OSPF_PACKET(a, b) \
|
||||
(conf_debug_ospf_packet[a] & OSPF_DEBUG_ ## b)
|
||||
#define IS_CONF_DEBUG_OSPF(a, b) \
|
||||
@ -119,6 +122,7 @@ extern unsigned long term_debug_ospf_nsm;
|
||||
extern unsigned long term_debug_ospf_lsa;
|
||||
extern unsigned long term_debug_ospf_zebra;
|
||||
extern unsigned long term_debug_ospf_nssa;
|
||||
extern unsigned long term_debug_ospf_te;
|
||||
|
||||
/* Message Strings. */
|
||||
extern char *ospf_lsa_type_str[];
|
||||
|
@ -213,6 +213,9 @@ ospf_opaque_type_name (u_char opaque_type)
|
||||
case OPAQUE_TYPE_GRACE_LSA:
|
||||
name = "Grace-LSA";
|
||||
break;
|
||||
case OPAQUE_TYPE_INTER_AS_LSA:
|
||||
name = "Inter-AS TE-v2 LSA";
|
||||
break;
|
||||
default:
|
||||
if (OPAQUE_TYPE_RANGE_UNASSIGNED (opaque_type))
|
||||
name = "Unassigned";
|
||||
@ -1979,6 +1982,7 @@ ospf_opaque_lsa_refresh_schedule (struct ospf_lsa *lsa0)
|
||||
struct opaque_info_per_type *oipt;
|
||||
struct opaque_info_per_id *oipi;
|
||||
struct ospf_lsa *lsa;
|
||||
struct ospf *top;
|
||||
int delay;
|
||||
|
||||
if ((oipt = lookup_opaque_info_by_type (lsa0)) == NULL
|
||||
@ -2010,7 +2014,10 @@ ospf_opaque_lsa_refresh_schedule (struct ospf_lsa *lsa0)
|
||||
ospf_ls_retransmit_delete_nbr_area (lsa->area, lsa);
|
||||
break;
|
||||
case OSPF_OPAQUE_AS_LSA:
|
||||
ospf_ls_retransmit_delete_nbr_as (lsa0->area->ospf, lsa);
|
||||
top = ospf_lookup ();
|
||||
if ((lsa0->area != NULL) && (lsa0->area->ospf != NULL))
|
||||
top = lsa0->area->ospf;
|
||||
ospf_ls_retransmit_delete_nbr_as (top, lsa);
|
||||
break;
|
||||
default:
|
||||
zlog_warn ("ospf_opaque_lsa_refresh_schedule: Unexpected LSA-type(%u)", lsa->data->type);
|
||||
@ -2055,6 +2062,9 @@ ospf_opaque_lsa_flush_schedule (struct ospf_lsa *lsa0)
|
||||
struct opaque_info_per_type *oipt;
|
||||
struct opaque_info_per_id *oipi;
|
||||
struct ospf_lsa *lsa;
|
||||
struct ospf *top;
|
||||
|
||||
top = ospf_lookup ();
|
||||
|
||||
if ((oipt = lookup_opaque_info_by_type (lsa0)) == NULL
|
||||
|| (oipi = lookup_opaque_info_by_id (oipt, lsa0)) == NULL)
|
||||
@ -2078,7 +2088,9 @@ ospf_opaque_lsa_flush_schedule (struct ospf_lsa *lsa0)
|
||||
ospf_ls_retransmit_delete_nbr_area (lsa->area, lsa);
|
||||
break;
|
||||
case OSPF_OPAQUE_AS_LSA:
|
||||
ospf_ls_retransmit_delete_nbr_as (lsa0->area->ospf, lsa);
|
||||
if ((lsa0->area != NULL) && (lsa0->area->ospf != NULL))
|
||||
top = lsa0->area->ospf;
|
||||
ospf_ls_retransmit_delete_nbr_as (top, lsa);
|
||||
break;
|
||||
default:
|
||||
zlog_warn ("ospf_opaque_lsa_flush_schedule: Unexpected LSA-type(%u)", lsa->data->type);
|
||||
@ -2102,7 +2114,7 @@ ospf_opaque_lsa_flush_schedule (struct ospf_lsa *lsa0)
|
||||
zlog_debug ("Schedule Type-%u Opaque-LSA to FLUSH: [opaque-type=%u, opaque-id=%x]", lsa->data->type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr)));
|
||||
|
||||
/* This lsa will be flushed and removed eventually. */
|
||||
ospf_lsa_flush (lsa0->area->ospf, lsa);
|
||||
ospf_lsa_flush (top, lsa);
|
||||
|
||||
out:
|
||||
return;
|
||||
@ -2144,28 +2156,6 @@ ospf_opaque_self_originated_lsa_received (struct ospf_neighbor *nbr,
|
||||
* Followings are util functions; probably be used by Opaque-LSAs only...
|
||||
*------------------------------------------------------------------------*/
|
||||
|
||||
void
|
||||
htonf (float *src, float *dst)
|
||||
{
|
||||
u_int32_t lu1, lu2;
|
||||
|
||||
memcpy (&lu1, src, sizeof (u_int32_t));
|
||||
lu2 = htonl (lu1);
|
||||
memcpy (dst, &lu2, sizeof (u_int32_t));
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
ntohf (float *src, float *dst)
|
||||
{
|
||||
u_int32_t lu1, lu2;
|
||||
|
||||
memcpy (&lu1, src, sizeof (u_int32_t));
|
||||
lu2 = ntohl (lu1);
|
||||
memcpy (dst, &lu2, sizeof (u_int32_t));
|
||||
return;
|
||||
}
|
||||
|
||||
struct ospf *
|
||||
oi_to_top (struct ospf_interface *oi)
|
||||
{
|
||||
|
@ -60,6 +60,10 @@
|
||||
#define OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA 1
|
||||
#define OPAQUE_TYPE_SYCAMORE_OPTICAL_TOPOLOGY_DESC 2
|
||||
#define OPAQUE_TYPE_GRACE_LSA 3
|
||||
#define OPAQUE_TYPE_L1VPN_LSA 5
|
||||
#define OPAQUE_TYPE_ROUTER_INFORMATION_LSA 4
|
||||
#define OPAQUE_TYPE_INTER_AS_LSA 6
|
||||
#define OPAQUE_TYPE_MAX 6
|
||||
|
||||
/* Followings types are proposed in internet-draft documents. */
|
||||
#define OPAQUE_TYPE_8021_QOSPF 129
|
||||
@ -70,7 +74,7 @@
|
||||
#define OPAQUE_TYPE_WILDCARD 0
|
||||
|
||||
#define OPAQUE_TYPE_RANGE_UNASSIGNED(type) \
|
||||
( 4 <= (type) && (type) <= 127)
|
||||
( OPAQUE_TYPE_MAX <= (type) && (type) <= 127)
|
||||
|
||||
#define OPAQUE_TYPE_RANGE_RESERVED(type) \
|
||||
(127 < (type) && (type) <= 255)
|
||||
@ -137,8 +141,6 @@ extern void ospf_opaque_lsa_flush_schedule (struct ospf_lsa *lsa);
|
||||
extern void ospf_opaque_self_originated_lsa_received (struct ospf_neighbor
|
||||
*nbr,
|
||||
struct ospf_lsa *lsa);
|
||||
extern void htonf (float *src, float *dst);
|
||||
extern void ntohf (float *src, float *dst);
|
||||
extern struct ospf *oi_to_top (struct ospf_interface *oi);
|
||||
|
||||
#endif /* _ZEBRA_OSPF_OPAQUE_H */
|
||||
|
@ -913,7 +913,7 @@ ospf_hello (struct ip *iph, struct ospf_header *ospfh,
|
||||
/* Compare options. */
|
||||
#define REJECT_IF_TBIT_ON 1 /* XXX */
|
||||
#ifdef REJECT_IF_TBIT_ON
|
||||
if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
|
||||
if (CHECK_FLAG (hello->options, OSPF_OPTION_MT))
|
||||
{
|
||||
/*
|
||||
* This router does not support non-zero TOS.
|
||||
@ -1265,7 +1265,7 @@ ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
|
||||
}
|
||||
|
||||
#ifdef REJECT_IF_TBIT_ON
|
||||
if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
|
||||
if (CHECK_FLAG (dd->options, OSPF_OPTION_MT))
|
||||
{
|
||||
/*
|
||||
* In Hello protocol, optional capability must have checked
|
||||
|
1930
ospfd/ospf_te.c
1930
ospfd/ospf_te.c
File diff suppressed because it is too large
Load Diff
281
ospfd/ospf_te.h
281
ospfd/ospf_te.h
@ -1,8 +1,11 @@
|
||||
/*
|
||||
* This is an implementation of draft-katz-yeung-ospf-traffic-06.txt
|
||||
* This is an implementation of RFC3630, RFC5392 & RFC6827
|
||||
* Copyright (C) 2001 KDD R&D Laboratories, Inc.
|
||||
* http://www.kddlabs.co.jp/
|
||||
*
|
||||
* Copyright (C) 2012 Orange Labs
|
||||
* http://www.orange.com
|
||||
*
|
||||
* This file is part of GNU Zebra.
|
||||
*
|
||||
* GNU Zebra is free software; you can redistribute it and/or modify it
|
||||
@ -21,6 +24,10 @@
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* Add support of RFC7471 */
|
||||
/* Add support of RFC5392 */
|
||||
/* Add support of RFC6827 (partial) */
|
||||
|
||||
#ifndef _ZEBRA_OSPF_MPLS_TE_H
|
||||
#define _ZEBRA_OSPF_MPLS_TE_H
|
||||
|
||||
@ -42,6 +49,7 @@
|
||||
*/
|
||||
|
||||
#define MAX_LEGAL_TE_INSTANCE_NUM (0xffff)
|
||||
#define LEGAL_TE_INSTANCE_RANGE(i) (0 <= (i) && (i) <= 0xffff)
|
||||
|
||||
/*
|
||||
* 24 16 8 0
|
||||
@ -62,6 +70,31 @@
|
||||
* +--------+--------+--------+--------+ ---
|
||||
*/
|
||||
|
||||
/* Following define the type of TE link regarding the various RFC */
|
||||
#define STD_TE 0x01
|
||||
#define GMPLS 0x02
|
||||
#define INTER_AS 0x04
|
||||
#define PSEUDO_TE 0x08
|
||||
#define FLOOD_AREA 0x10
|
||||
#define FLOOD_AS 0x20
|
||||
#define EMULATED 0x80
|
||||
|
||||
#define IS_STD_TE(x) (x & STD_TE)
|
||||
#define IS_PSEUDO_TE(x) (x & PSEUDO_TE)
|
||||
#define IS_INTER_AS(x) (x & INTER_AS)
|
||||
#define IS_EMULATED(x) (x & EMULATED)
|
||||
#define IS_FLOOD_AREA(x) (x & FLOOD_AREA)
|
||||
#define IS_FLOOD_AS(x) (x & FLOOD_AS)
|
||||
#define IS_INTER_AS_EMU(x) (x & INTER_AS & EMULATED)
|
||||
#define IS_INTER_AS_AS(x) (x & INTER_AS & FLOOD_AS)
|
||||
|
||||
/* Flags to manage TE Link LSA */
|
||||
#define LPFLG_LSA_INACTIVE 0x0
|
||||
#define LPFLG_LSA_ACTIVE 0x1
|
||||
#define LPFLG_LSA_ENGAGED 0x2
|
||||
#define LPFLG_LOOKUP_DONE 0x4
|
||||
#define LPFLG_LSA_FORCED_REFRESH 0x8
|
||||
|
||||
/*
|
||||
* Following section defines TLV (tag, length, value) structures,
|
||||
* used for Traffic Engineering.
|
||||
@ -87,6 +120,14 @@ struct te_tlv_header
|
||||
#define TLV_HDR_NEXT(tlvh) \
|
||||
(struct te_tlv_header *)((char *)(tlvh) + TLV_SIZE(tlvh))
|
||||
|
||||
#define TLV_HDR_SUBTLV(tlvh) \
|
||||
(struct te_tlv_header *)((char *)(tlvh) + TLV_HDR_SIZE)
|
||||
|
||||
#define TLV_TYPE(tlvh) tlvh.header.type
|
||||
#define TLV_LEN(tlvh) tlvh.header.length
|
||||
#define TLV_HDR(tlvh) tlvh.header
|
||||
|
||||
|
||||
/*
|
||||
* Following section defines TLV body parts.
|
||||
*/
|
||||
@ -106,12 +147,16 @@ struct te_tlv_link
|
||||
/* A set of link-sub-TLVs will follow. */
|
||||
};
|
||||
|
||||
#define TE_LINK_SUBTLV_DEF_SIZE 4
|
||||
|
||||
/* Link Type Sub-TLV */ /* Mandatory */
|
||||
#define TE_LINK_SUBTLV_LINK_TYPE 1
|
||||
#define TE_LINK_SUBTLV_TYPE_SIZE 1
|
||||
struct te_link_subtlv_link_type
|
||||
{
|
||||
struct te_tlv_header header; /* Value length is 1 octet. */
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
#define LINK_TYPE_SUBTLV_VALUE_PTP 1
|
||||
#define LINK_TYPE_SUBTLV_VALUE_MA 2
|
||||
u_char value;
|
||||
@ -169,10 +214,11 @@ struct te_link_subtlv_max_rsv_bw
|
||||
|
||||
/* Link Sub-TLV: Unreserved Bandwidth */ /* Optional */
|
||||
#define TE_LINK_SUBTLV_UNRSV_BW 8
|
||||
#define TE_LINK_SUBTLV_UNRSV_SIZE 32
|
||||
struct te_link_subtlv_unrsv_bw
|
||||
{
|
||||
struct te_tlv_header header; /* Value length is 32 octets. */
|
||||
float value[8]; /* One for each priority level. */
|
||||
float value[MAX_CLASS_TYPE]; /* One for each priority level. */
|
||||
};
|
||||
|
||||
/* Link Sub-TLV: Resource Class/Color */ /* Optional */
|
||||
@ -183,11 +229,238 @@ struct te_link_subtlv_rsc_clsclr
|
||||
u_int32_t value; /* Admin. group membership. */
|
||||
};
|
||||
|
||||
/* Here are "non-official" architechtual constants. */
|
||||
/* For RFC6827 */
|
||||
/* Local and Remote TE Router ID */
|
||||
#define TE_LINK_SUBTLV_LRRID 10
|
||||
#define TE_LINK_SUBTLV_LRRID_SIZE 8
|
||||
struct te_link_subtlv_lrrid
|
||||
{
|
||||
struct te_tlv_header header; /* Value length is 8 octets. */
|
||||
struct in_addr local; /* Local TE Router Identifier */
|
||||
struct in_addr remote; /* Remote TE Router Identifier */
|
||||
};
|
||||
|
||||
/* RFC4203: Link Local/Remote Identifiers */
|
||||
#define TE_LINK_SUBTLV_LLRI 11
|
||||
#define TE_LINK_SUBTLV_LLRI_SIZE 8
|
||||
struct te_link_subtlv_llri
|
||||
{
|
||||
struct te_tlv_header header; /* Value length is 8 octets. */
|
||||
u_int32_t local; /* Link Local Identifier */
|
||||
u_int32_t remote; /* Link Remote Identifier */
|
||||
};
|
||||
|
||||
/* Inter-RA Export Upward sub-TLV (12) and Inter-RA Export Downward sub-TLV (13) (RFC6827bis) are not yet supported */
|
||||
/* SUBTLV 14-16 (RFC4203) are not yet supported */
|
||||
/* Bandwidth Constraints sub-TLV (17) (RFC4124) is not yet supported */
|
||||
/* SUBLV 18-20 are for OSPFv6 TE (RFC5329). see ospf6d */
|
||||
|
||||
/* For RFC 5392 */
|
||||
/* Remote AS Number sub-TLV */
|
||||
#define TE_LINK_SUBTLV_RAS 21
|
||||
struct te_link_subtlv_ras
|
||||
{
|
||||
struct te_tlv_header header; /* Value length is 4 octets. */
|
||||
u_int32_t value; /* Remote AS number */
|
||||
};
|
||||
|
||||
/* IPv4 Remote ASBR ID Sub-TLV */
|
||||
#define TE_LINK_SUBTLV_RIP 22
|
||||
struct te_link_subtlv_rip
|
||||
{
|
||||
struct te_tlv_header header; /* Value length is 4 octets. */
|
||||
struct in_addr value; /* Remote ASBR IP address */
|
||||
};
|
||||
|
||||
/* SUBTLV 24 is IPv6 Remote ASBR ID (RFC5392). see ospf6d */
|
||||
|
||||
/* SUBTLV 23 (RFC5330) and 25 (RFC6001) are not yet supported */
|
||||
|
||||
/* SUBTLV 26 (RFC7308) is not yet supported */
|
||||
|
||||
/* RFC7471 */
|
||||
/* Link Sub-TLV: Average Link Delay */ /* Optional */
|
||||
#define TE_LINK_SUBTLV_AV_DELAY 27
|
||||
struct te_link_subtlv_av_delay
|
||||
{
|
||||
struct te_tlv_header header; /* Value length is 4 bytes. */
|
||||
u_int32_t value; /* delay in micro-seconds only 24 bits => 0 ... 16777215
|
||||
with Anomalous Bit as Upper most bit */
|
||||
};
|
||||
|
||||
/* Link Sub-TLV: Low/High Link Delay */
|
||||
#define TE_LINK_SUBTLV_MM_DELAY 28
|
||||
#define TE_LINK_SUBTLV_MM_DELAY_SIZE 8
|
||||
struct te_link_subtlv_mm_delay
|
||||
{
|
||||
struct te_tlv_header header; /* Value length is 8 bytes. */
|
||||
u_int32_t low; /* low delay in micro-seconds only 24 bits => 0 ... 16777215
|
||||
with Anomalous Bit (A) as Upper most bit */
|
||||
u_int32_t high; /* high delay in micro-seconds only 24 bits => 0 ... 16777215 */
|
||||
};
|
||||
|
||||
/* Link Sub-TLV: Link Delay Variation i.e. Jitter */
|
||||
#define TE_LINK_SUBTLV_DELAY_VAR 29
|
||||
struct te_link_subtlv_delay_var
|
||||
{
|
||||
struct te_tlv_header header; /* Value length is 4 bytes. */
|
||||
u_int32_t value; /* interval in micro-seconds only 24 bits => 0 ... 16777215 */
|
||||
};
|
||||
|
||||
/* Link Sub-TLV: Routine Unidirectional Link Packet Loss */
|
||||
#define TE_LINK_SUBTLV_PKT_LOSS 30
|
||||
struct te_link_subtlv_pkt_loss
|
||||
{
|
||||
struct te_tlv_header header; /* Value length is 4 bytes. */
|
||||
u_int32_t value; /* in percentage of total traffic only 24 bits (2^24 - 2)
|
||||
with Anomalous Bit as Upper most bit */
|
||||
};
|
||||
|
||||
/* Link Sub-TLV: Unidirectional Residual Bandwidth */ /* Optional */
|
||||
#define TE_LINK_SUBTLV_RES_BW 31
|
||||
struct te_link_subtlv_res_bw
|
||||
{
|
||||
struct te_tlv_header header; /* Value length is 4 bytes. */
|
||||
float value; /* bandwidth in IEEE floating point format with units in bytes per second */
|
||||
};
|
||||
|
||||
/* Link Sub-TLV: Unidirectional Available Bandwidth */ /* Optional */
|
||||
#define TE_LINK_SUBTLV_AVA_BW 32
|
||||
struct te_link_subtlv_ava_bw
|
||||
{
|
||||
struct te_tlv_header header; /* Value length is 4 octets. */
|
||||
float value; /* bandwidth in IEEE floating point format with units in bytes per second */
|
||||
};
|
||||
|
||||
/* Link Sub-TLV: Unidirectional Utilized Bandwidth */ /* Optional */
|
||||
#define TE_LINK_SUBTLV_USE_BW 33
|
||||
struct te_link_subtlv_use_bw
|
||||
{
|
||||
struct te_tlv_header header; /* Value length is 4 octets. */
|
||||
float value; /* bandwidth in IEEE floating point format with units in bytes per second */
|
||||
};
|
||||
|
||||
#define TE_LINK_SUBTLV_MAX 34 /* Last SUBTLV + 1 */
|
||||
|
||||
/* Here are "non-official" architectural constants. */
|
||||
#define MPLS_TE_MINIMUM_BANDWIDTH 1.0 /* Reasonable? *//* XXX */
|
||||
|
||||
/* Following declaration concerns the MPLS-TE and LINk-TE management */
|
||||
typedef enum _opcode_t
|
||||
{ REORIGINATE_THIS_LSA, REFRESH_THIS_LSA, FLUSH_THIS_LSA } opcode_t;
|
||||
|
||||
typedef enum _status_t
|
||||
{ disabled, enabled } status_t;
|
||||
|
||||
/* Mode for Inter-AS Opaque-LSA */
|
||||
enum inter_as_mode { Disable, AS, Area };
|
||||
|
||||
struct te_link_subtlv
|
||||
{
|
||||
struct te_tlv_header header;
|
||||
union
|
||||
{
|
||||
u_int32_t link_type;
|
||||
struct in_addr link_id;
|
||||
struct in_addr lclif;
|
||||
struct in_addr rmtif;
|
||||
u_int32_t te_metric;
|
||||
float max_bw;
|
||||
float max_rsv_bw;
|
||||
float unrsv[8];
|
||||
u_int32_t rsc_clsclr;
|
||||
u_int32_t llri[2];
|
||||
u_int32_t ras;
|
||||
struct in_addr rip;
|
||||
struct in_addr lrrid[2];
|
||||
u_int32_t av_delay;
|
||||
u_int32_t mm_delay;
|
||||
u_int32_t delay_var;
|
||||
u_int32_t pkt_loss;
|
||||
float res_bw;
|
||||
float ava_bw;
|
||||
float use_bw;
|
||||
} value;
|
||||
};
|
||||
|
||||
/* Following structure are internal use only. */
|
||||
struct ospf_mpls_te
|
||||
{
|
||||
/* Status of MPLS-TE: enable or disbale */
|
||||
status_t status;
|
||||
|
||||
/* RFC5392 */
|
||||
enum inter_as_mode inter_as;
|
||||
struct in_addr interas_areaid;
|
||||
|
||||
/* List elements are zebra-interfaces (ifp), not ospf-interfaces (oi). */
|
||||
struct list *iflist;
|
||||
|
||||
/* Store Router-TLV in network byte order. */
|
||||
struct te_tlv_router_addr router_addr;
|
||||
};
|
||||
|
||||
struct mpls_te_link
|
||||
{
|
||||
/*
|
||||
* According to MPLS-TE (draft) specification, 24-bit Opaque-ID field
|
||||
* is subdivided into 8-bit "unused" field and 16-bit "instance" field.
|
||||
* In this implementation, each Link-TLV has its own instance.
|
||||
*/
|
||||
u_int32_t instance;
|
||||
|
||||
/* Reference pointer to a Zebra-interface. */
|
||||
struct interface *ifp;
|
||||
|
||||
/* Area info in which this MPLS-TE link belongs to. */
|
||||
struct ospf_area *area;
|
||||
|
||||
/* Flags to manage this link parameters. */
|
||||
u_int32_t flags;
|
||||
|
||||
/* Type of MPLS-TE link: RFC3630, RFC5392, RFC5392 emulated, RFC6827 */
|
||||
u_int8_t type;
|
||||
|
||||
/* Store Link-TLV in network byte order. */
|
||||
/* RFC3630 & RFC6827 / RFC 6827 */
|
||||
struct te_tlv_link link_header;
|
||||
struct te_link_subtlv_link_type link_type;
|
||||
struct te_link_subtlv_link_id link_id;
|
||||
struct te_link_subtlv_lclif_ipaddr lclif_ipaddr;
|
||||
struct te_link_subtlv_rmtif_ipaddr rmtif_ipaddr;
|
||||
struct te_link_subtlv_te_metric te_metric;
|
||||
struct te_link_subtlv_max_bw max_bw;
|
||||
struct te_link_subtlv_max_rsv_bw max_rsv_bw;
|
||||
struct te_link_subtlv_unrsv_bw unrsv_bw;
|
||||
struct te_link_subtlv_rsc_clsclr rsc_clsclr;
|
||||
/* RFC4203 */
|
||||
struct te_link_subtlv_llri llri;
|
||||
/* RFC5392 */
|
||||
struct te_link_subtlv_ras ras;
|
||||
struct te_link_subtlv_rip rip;
|
||||
/* RFC6827 */
|
||||
struct te_link_subtlv_lrrid lrrid;
|
||||
/* RFC7471 */
|
||||
struct te_link_subtlv_av_delay av_delay;
|
||||
struct te_link_subtlv_mm_delay mm_delay;
|
||||
struct te_link_subtlv_delay_var delay_var;
|
||||
struct te_link_subtlv_pkt_loss pkt_loss;
|
||||
struct te_link_subtlv_res_bw res_bw;
|
||||
struct te_link_subtlv_ava_bw ava_bw;
|
||||
struct te_link_subtlv_use_bw use_bw;
|
||||
|
||||
struct in_addr adv_router;
|
||||
struct in_addr id;
|
||||
};
|
||||
|
||||
/* Prototypes. */
|
||||
extern int ospf_mpls_te_init (void);
|
||||
extern void ospf_mpls_te_term (void);
|
||||
extern struct ospf_mpls_te *get_ospf_mpls_te (void);
|
||||
extern void ospf_mpls_te_update_if (struct interface *);
|
||||
extern void ospf_mpls_te_lsa_schedule (struct mpls_te_link *, opcode_t);
|
||||
extern u_int32_t get_mpls_te_instance_value (void);
|
||||
extern void set_linkparams_llri (struct mpls_te_link *, u_int32_t, u_int32_t);
|
||||
extern void set_linkparams_lrrid (struct mpls_te_link *, struct in_addr, struct in_addr);
|
||||
|
||||
#endif /* _ZEBRA_OSPF_MPLS_TE_H */
|
||||
|
@ -64,7 +64,7 @@ static const char *ospf_network_type_str[] =
|
||||
};
|
||||
|
||||
/* Utility functions. */
|
||||
static int
|
||||
int
|
||||
ospf_str2area_id (const char *str, struct in_addr *area_id, int *format)
|
||||
{
|
||||
char *endptr = NULL;
|
||||
|
@ -54,5 +54,6 @@
|
||||
extern void ospf_vty_init (void);
|
||||
extern void ospf_vty_show_init (void);
|
||||
extern void ospf_vty_clear_init (void);
|
||||
extern int ospf_str2area_id (const char *, struct in_addr *, int *);
|
||||
|
||||
#endif /* _QUAGGA_OSPF_VTY_H */
|
||||
|
@ -53,6 +53,7 @@
|
||||
#ifdef HAVE_SNMP
|
||||
#include "ospfd/ospf_snmp.h"
|
||||
#endif /* HAVE_SNMP */
|
||||
#include "ospfd/ospf_te.h"
|
||||
|
||||
/* Zebra structure to hold current status. */
|
||||
struct zclient *zclient = NULL;
|
||||
@ -331,6 +332,24 @@ ospf_interface_address_delete (int command, struct zclient *zclient,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ospf_interface_link_params (int command, struct zclient *zclient,
|
||||
zebra_size_t length)
|
||||
{
|
||||
struct interface *ifp;
|
||||
|
||||
ifp = zebra_interface_link_params_read (zclient->ibuf);
|
||||
|
||||
if (ifp == NULL)
|
||||
return 0;
|
||||
|
||||
/* Update TE TLV */
|
||||
ospf_mpls_te_update_if (ifp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or)
|
||||
{
|
||||
@ -1580,6 +1599,8 @@ ospf_zebra_init (struct thread_master *master, u_short instance)
|
||||
zclient->interface_down = ospf_interface_state_down;
|
||||
zclient->interface_address_add = ospf_interface_address_add;
|
||||
zclient->interface_address_delete = ospf_interface_address_delete;
|
||||
zclient->interface_link_params = ospf_interface_link_params;
|
||||
|
||||
zclient->ipv4_route_add = ospf_zebra_read_ipv4;
|
||||
zclient->ipv4_route_delete = ospf_zebra_read_ipv4;
|
||||
zclient->redistribute_route_ipv4_add = ospf_zebra_read_ipv4;
|
||||
|
@ -305,7 +305,7 @@ ospf_lookup ()
|
||||
if (listcount (om->ospf) == 0)
|
||||
return NULL;
|
||||
|
||||
return listgetdata (listhead (om->ospf));
|
||||
return listgetdata ((struct listnode *)listhead (om->ospf));
|
||||
}
|
||||
|
||||
struct ospf *
|
||||
|
@ -59,13 +59,14 @@
|
||||
#define OSPF_AUTH_CMD_NOTSEEN -2
|
||||
|
||||
/* OSPF options. */
|
||||
#define OSPF_OPTION_T 0x01 /* TOS. */
|
||||
#define OSPF_OPTION_MT 0x01 /* M/T */
|
||||
#define OSPF_OPTION_E 0x02
|
||||
#define OSPF_OPTION_MC 0x04
|
||||
#define OSPF_OPTION_NP 0x08
|
||||
#define OSPF_OPTION_EA 0x10
|
||||
#define OSPF_OPTION_DC 0x20
|
||||
#define OSPF_OPTION_O 0x40
|
||||
#define OSPF_OPTION_DN 0x80
|
||||
|
||||
/* OSPF Database Description flags. */
|
||||
#define OSPF_DD_FLAG_MS 0x01
|
||||
|
@ -36,6 +36,7 @@ EOF
|
||||
$ignore{'"interface IFNAME"'} = "ignore";
|
||||
$ignore{'"interface IFNAME " "vrf <0-65535>"'} = "ignore";
|
||||
$ignore{'"interface IFNAME " "vrf NAME"'} = "ignore";
|
||||
$ignore{'"link-params"'} = "ignore";
|
||||
$ignore{'"vrf NAME"'} = "ignore";
|
||||
$ignore{'"ip vrf NAME"'} = "ignore";
|
||||
$ignore{'"router rip"'} = "ignore";
|
||||
|
@ -1032,6 +1032,12 @@ static struct cmd_node keychain_key_node =
|
||||
"%s(config-keychain-key)# "
|
||||
};
|
||||
|
||||
struct cmd_node link_params_node =
|
||||
{
|
||||
LINK_PARAMS_NODE,
|
||||
"%s(config-link-params)# ",
|
||||
};
|
||||
|
||||
/* Defined in lib/vty.c */
|
||||
extern struct cmd_node vty_node;
|
||||
|
||||
@ -1414,6 +1420,9 @@ vtysh_exit (struct vty *vty)
|
||||
case KEYCHAIN_KEY_NODE:
|
||||
vty->node = KEYCHAIN_NODE;
|
||||
break;
|
||||
case LINK_PARAMS_NODE:
|
||||
vty->node = INTERFACE_NODE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1746,6 +1755,17 @@ DEFUN (vtysh_show_work_queues_daemon,
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEFUNSH (VTYSH_ZEBRA,
|
||||
vtysh_link_params,
|
||||
vtysh_link_params_cmd,
|
||||
"link-params",
|
||||
LINK_PARAMS_STR
|
||||
)
|
||||
{
|
||||
vty->node = LINK_PARAMS_NODE;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/* Memory */
|
||||
DEFUN (vtysh_show_memory,
|
||||
vtysh_show_memory_cmd,
|
||||
@ -2843,6 +2863,7 @@ vtysh_init_vty (void)
|
||||
install_node (&bgp_node, NULL);
|
||||
install_node (&rip_node, NULL);
|
||||
install_node (&interface_node, NULL);
|
||||
install_node (&link_params_node, NULL);
|
||||
install_node (&vrf_node, NULL);
|
||||
install_node (&rmap_node, NULL);
|
||||
install_node (&zebra_node, NULL);
|
||||
@ -2872,6 +2893,7 @@ vtysh_init_vty (void)
|
||||
vtysh_install_default (BGP_NODE);
|
||||
vtysh_install_default (RIP_NODE);
|
||||
vtysh_install_default (INTERFACE_NODE);
|
||||
vtysh_install_default (LINK_PARAMS_NODE);
|
||||
vtysh_install_default (VRF_NODE);
|
||||
vtysh_install_default (RMAP_NODE);
|
||||
vtysh_install_default (ZEBRA_NODE);
|
||||
@ -2965,6 +2987,8 @@ vtysh_init_vty (void)
|
||||
install_element (INTERFACE_NODE, &no_interface_desc_cmd);
|
||||
install_element (INTERFACE_NODE, &vtysh_end_all_cmd);
|
||||
install_element (INTERFACE_NODE, &vtysh_exit_interface_cmd);
|
||||
install_element (LINK_PARAMS_NODE, &vtysh_end_all_cmd);
|
||||
install_element (LINK_PARAMS_NODE, &vtysh_exit_interface_cmd);
|
||||
install_element (INTERFACE_NODE, &vtysh_quit_interface_cmd);
|
||||
|
||||
install_element (VRF_NODE, &vtysh_end_all_cmd);
|
||||
@ -3015,6 +3039,7 @@ vtysh_init_vty (void)
|
||||
install_element (CONFIG_NODE, &vtysh_no_interface_cmd);
|
||||
install_element (CONFIG_NODE, &vtysh_interface_vrf_cmd);
|
||||
install_element (CONFIG_NODE, &vtysh_no_interface_vrf_cmd);
|
||||
install_element (INTERFACE_NODE, &vtysh_link_params_cmd);
|
||||
install_element (ENABLE_NODE, &vtysh_show_running_config_cmd);
|
||||
install_element (ENABLE_NODE, &vtysh_show_running_config_daemon_cmd);
|
||||
install_element (ENABLE_NODE, &vtysh_copy_runningconfig_startupconfig_cmd);
|
||||
|
@ -281,7 +281,7 @@ if_subnet_delete (struct interface *ifp, struct connected *ifc)
|
||||
/* If deleted address is primary, mark subsequent one as such and distribute. */
|
||||
if (! CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
|
||||
{
|
||||
ifc = listgetdata (listhead (addr_list));
|
||||
ifc = listgetdata ((struct listnode *)listhead (addr_list));
|
||||
zebra_interface_address_delete_update (ifp, ifc);
|
||||
UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
|
||||
/* XXX: Linux kernel removes all the secondary addresses when the primary
|
||||
@ -1086,6 +1086,53 @@ if_dump_vty (struct vty *vty, struct interface *ifp)
|
||||
connected_dump_vty (vty, connected);
|
||||
}
|
||||
|
||||
if (HAS_LINK_PARAMS(ifp))
|
||||
{
|
||||
int i;
|
||||
struct if_link_params *iflp = ifp->link_params;
|
||||
vty_out(vty, " Traffic Engineering Link Parameters:%s", VTY_NEWLINE);
|
||||
if (IS_PARAM_SET(iflp, LP_TE))
|
||||
vty_out(vty, " TE metric %u%s",iflp->te_metric, VTY_NEWLINE);
|
||||
if (IS_PARAM_SET(iflp, LP_MAX_BW))
|
||||
vty_out(vty, " Maximum Bandwidth %g (Byte/s)%s", iflp->max_bw, VTY_NEWLINE);
|
||||
if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW))
|
||||
vty_out(vty, " Maximum Reservable Bandwidth %g (Byte/s)%s", iflp->max_rsv_bw, VTY_NEWLINE);
|
||||
if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) {
|
||||
vty_out(vty, " Unreserved Bandwidth per Class Type in Byte/s:%s", VTY_NEWLINE);
|
||||
for (i = 0; i < MAX_CLASS_TYPE; i+=2)
|
||||
vty_out(vty, " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)%s",
|
||||
i, iflp->unrsv_bw[i], i+1, iflp->unrsv_bw[i+1], VTY_NEWLINE);
|
||||
}
|
||||
|
||||
if (IS_PARAM_SET(iflp, LP_ADM_GRP))
|
||||
vty_out(vty, " Administrative Group:%u%s", iflp->admin_grp, VTY_NEWLINE);
|
||||
if (IS_PARAM_SET(iflp, LP_DELAY))
|
||||
{
|
||||
vty_out(vty, " Link Delay Average: %u (micro-sec.)", iflp->av_delay);
|
||||
if (IS_PARAM_SET(iflp, LP_MM_DELAY))
|
||||
{
|
||||
vty_out(vty, " Min: %u (micro-sec.)", iflp->min_delay);
|
||||
vty_out(vty, " Max: %u (micro-sec.)", iflp->max_delay);
|
||||
}
|
||||
vty_out(vty, "%s", VTY_NEWLINE);
|
||||
}
|
||||
if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
|
||||
vty_out(vty, " Link Delay Variation %u (micro-sec.)%s", iflp->delay_var, VTY_NEWLINE);
|
||||
if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
|
||||
vty_out(vty, " Link Packet Loss %g (in %%)%s", iflp->pkt_loss, VTY_NEWLINE);
|
||||
if (IS_PARAM_SET(iflp, LP_AVA_BW))
|
||||
vty_out(vty, " Available Bandwidth %g (Byte/s)%s", iflp->ava_bw, VTY_NEWLINE);
|
||||
if (IS_PARAM_SET(iflp, LP_RES_BW))
|
||||
vty_out(vty, " Residual Bandwidth %g (Byte/s)%s", iflp->res_bw, VTY_NEWLINE);
|
||||
if (IS_PARAM_SET(iflp, LP_USE_BW))
|
||||
vty_out(vty, " Utilized Bandwidth %g (Byte/s)%s", iflp->use_bw, VTY_NEWLINE);
|
||||
if (IS_PARAM_SET(iflp, LP_RMT_AS))
|
||||
vty_out(vty, " Neighbor ASBR IP: %s AS: %u %s", inet_ntoa(iflp->rmt_ip), iflp->rmt_as, VTY_NEWLINE);
|
||||
}
|
||||
|
||||
#ifdef RTADV
|
||||
nd_dump_vty (vty, ifp);
|
||||
#endif /* RTADV */
|
||||
#if defined (HAVE_RTADV)
|
||||
nd_dump_vty (vty, ifp);
|
||||
#endif /* HAVE_RTADV */
|
||||
@ -1690,6 +1737,692 @@ ALIAS (no_bandwidth_if,
|
||||
"Set bandwidth informational parameter\n"
|
||||
"Bandwidth in megabits\n")
|
||||
|
||||
struct cmd_node link_params_node =
|
||||
{
|
||||
LINK_PARAMS_NODE,
|
||||
"%s(config-link-params)# ",
|
||||
1,
|
||||
};
|
||||
|
||||
static void
|
||||
link_param_cmd_set_uint32 (struct interface *ifp, uint32_t *field,
|
||||
uint32_t type, uint32_t value)
|
||||
{
|
||||
/* Update field as needed */
|
||||
if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value)
|
||||
{
|
||||
*field = value;
|
||||
SET_PARAM(ifp->link_params, type);
|
||||
|
||||
/* force protocols to update LINK STATE due to parameters change */
|
||||
if (if_is_operative (ifp))
|
||||
zebra_interface_parameters_update (ifp);
|
||||
}
|
||||
}
|
||||
static void
|
||||
link_param_cmd_set_float (struct interface *ifp, float *field,
|
||||
uint32_t type, float value)
|
||||
{
|
||||
|
||||
/* Update field as needed */
|
||||
if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value)
|
||||
{
|
||||
*field = value;
|
||||
SET_PARAM(ifp->link_params, type);
|
||||
|
||||
/* force protocols to update LINK STATE due to parameters change */
|
||||
if (if_is_operative (ifp))
|
||||
zebra_interface_parameters_update (ifp);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
link_param_cmd_unset (struct interface *ifp, uint32_t type)
|
||||
{
|
||||
|
||||
/* Unset field */
|
||||
UNSET_PARAM(ifp->link_params, type);
|
||||
|
||||
/* force protocols to update LINK STATE due to parameters change */
|
||||
if (if_is_operative (ifp))
|
||||
zebra_interface_parameters_update (ifp);
|
||||
}
|
||||
|
||||
DEFUN (link_params,
|
||||
link_params_cmd,
|
||||
"link-params",
|
||||
LINK_PARAMS_STR)
|
||||
{
|
||||
vty->node = LINK_PARAMS_NODE;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/* Specific Traffic Engineering parameters commands */
|
||||
DEFUN (link_params_enable,
|
||||
link_params_enable_cmd,
|
||||
"enable",
|
||||
"Activate link parameters on this interface\n")
|
||||
{
|
||||
struct interface *ifp = (struct interface *) vty->index;
|
||||
|
||||
/* This command could be issue at startup, when activate MPLS TE */
|
||||
/* on a new interface or after a ON / OFF / ON toggle */
|
||||
/* In all case, TE parameters are reset to their default factory */
|
||||
if (IS_ZEBRA_DEBUG_EVENT)
|
||||
zlog_debug ("Link-params: enable TE link parameters on interface %s", ifp->name);
|
||||
|
||||
if (!if_link_params_get (ifp))
|
||||
{
|
||||
if (IS_ZEBRA_DEBUG_EVENT)
|
||||
zlog_debug ("Link-params: failed to init TE link parameters %s", ifp->name);
|
||||
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
/* force protocols to update LINK STATE due to parameters change */
|
||||
if (if_is_operative (ifp))
|
||||
zebra_interface_parameters_update (ifp);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (no_link_params_enable,
|
||||
no_link_params_enable_cmd,
|
||||
"no enable",
|
||||
NO_STR
|
||||
"Disable link parameters on this interface\n")
|
||||
{
|
||||
struct interface *ifp = (struct interface *) vty->index;
|
||||
|
||||
zlog_debug ("MPLS-TE: disable TE link parameters on interface %s", ifp->name);
|
||||
|
||||
if_link_params_free (ifp);
|
||||
|
||||
/* force protocols to update LINK STATE due to parameters change */
|
||||
if (if_is_operative (ifp))
|
||||
zebra_interface_parameters_update (ifp);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/* STANDARD TE metrics */
|
||||
DEFUN (link_params_metric,
|
||||
link_params_metric_cmd,
|
||||
"metric <0-4294967295>",
|
||||
"Link metric for MPLS-TE purpose\n"
|
||||
"Metric value in decimal\n")
|
||||
{
|
||||
struct interface *ifp = (struct interface *) vty->index;
|
||||
struct if_link_params *iflp = if_link_params_get (ifp);
|
||||
u_int32_t metric;
|
||||
|
||||
VTY_GET_ULONG("metric", metric, argv[0]);
|
||||
|
||||
/* Update TE metric if needed */
|
||||
link_param_cmd_set_uint32 (ifp, &iflp->te_metric, LP_TE, metric);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (no_link_params_metric,
|
||||
no_link_params_metric_cmd,
|
||||
"no metric",
|
||||
NO_STR
|
||||
"Disbale Link Metric on this interface\n")
|
||||
{
|
||||
struct interface *ifp = (struct interface *) vty->index;
|
||||
|
||||
/* Unset TE Metric */
|
||||
link_param_cmd_unset(ifp, LP_TE);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (link_params_maxbw,
|
||||
link_params_maxbw_cmd,
|
||||
"max-bw BANDWIDTH",
|
||||
"Maximum bandwidth that can be used\n"
|
||||
"Bytes/second (IEEE floating point format)\n")
|
||||
{
|
||||
struct interface *ifp = (struct interface *) vty->index;
|
||||
struct if_link_params *iflp = if_link_params_get (ifp);
|
||||
|
||||
float bw;
|
||||
|
||||
if (sscanf (argv[0], "%g", &bw) != 1)
|
||||
{
|
||||
vty_out (vty, "link_params_maxbw: fscanf: %s%s", safe_strerror (errno),
|
||||
VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
/* Check that Maximum bandwidth is not lower than other bandwidth parameters */
|
||||
if ((bw <= iflp->max_rsv_bw)
|
||||
|| (bw <= iflp->unrsv_bw[0])
|
||||
|| (bw <= iflp->unrsv_bw[1])
|
||||
|| (bw <= iflp->unrsv_bw[2])
|
||||
|| (bw <= iflp->unrsv_bw[3])
|
||||
|| (bw <= iflp->unrsv_bw[4])
|
||||
|| (bw <= iflp->unrsv_bw[5])
|
||||
|| (bw <= iflp->unrsv_bw[6])
|
||||
|| (bw <= iflp->unrsv_bw[7])
|
||||
|| (bw <= iflp->ava_bw)
|
||||
|| (bw <= iflp->res_bw)
|
||||
|| (bw <= iflp->use_bw))
|
||||
{
|
||||
vty_out (vty,
|
||||
"Maximum Bandwidth could not be lower than others bandwidth%s",
|
||||
VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
/* Update Maximum Bandwidth if needed */
|
||||
link_param_cmd_set_float (ifp, &iflp->max_bw, LP_MAX_BW, bw);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (link_params_max_rsv_bw,
|
||||
link_params_max_rsv_bw_cmd,
|
||||
"max-rsv-bw BANDWIDTH",
|
||||
"Maximum bandwidth that may be reserved\n"
|
||||
"Bytes/second (IEEE floating point format)\n")
|
||||
{
|
||||
struct interface *ifp = (struct interface *) vty->index;
|
||||
struct if_link_params *iflp = if_link_params_get (ifp);
|
||||
float bw;
|
||||
|
||||
if (sscanf (argv[0], "%g", &bw) != 1)
|
||||
{
|
||||
vty_out (vty, "link_params_max_rsv_bw: fscanf: %s%s", safe_strerror (errno),
|
||||
VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
/* Check that bandwidth is not greater than maximum bandwidth parameter */
|
||||
if (bw > iflp->max_bw)
|
||||
{
|
||||
vty_out (vty,
|
||||
"Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
|
||||
iflp->max_bw, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
/* Update Maximum Reservable Bandwidth if needed */
|
||||
link_param_cmd_set_float (ifp, &iflp->max_rsv_bw, LP_MAX_RSV_BW, bw);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (link_params_unrsv_bw,
|
||||
link_params_unrsv_bw_cmd,
|
||||
"unrsv-bw <0-7> BANDWIDTH",
|
||||
"Unreserved bandwidth at each priority level\n"
|
||||
"Priority\n"
|
||||
"Bytes/second (IEEE floating point format)\n")
|
||||
{
|
||||
struct interface *ifp = (struct interface *) vty->index;
|
||||
struct if_link_params *iflp = if_link_params_get (ifp);
|
||||
int priority;
|
||||
float bw;
|
||||
|
||||
/* We don't have to consider about range check here. */
|
||||
if (sscanf (argv[0], "%d", &priority) != 1)
|
||||
{
|
||||
vty_out (vty, "link_params_unrsv_bw: fscanf: %s%s", safe_strerror (errno),
|
||||
VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
if (sscanf (argv[1], "%g", &bw) != 1)
|
||||
{
|
||||
vty_out (vty, "link_params_unrsv_bw: fscanf: %s%s", safe_strerror (errno),
|
||||
VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
/* Check that bandwidth is not greater than maximum bandwidth parameter */
|
||||
if (bw > iflp->max_bw)
|
||||
{
|
||||
vty_out (vty,
|
||||
"UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
|
||||
iflp->max_bw, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
/* Update Unreserved Bandwidth if needed */
|
||||
link_param_cmd_set_float (ifp, &iflp->unrsv_bw[priority], LP_UNRSV_BW, bw);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (link_params_admin_grp,
|
||||
link_params_admin_grp_cmd,
|
||||
"admin-grp BITPATTERN",
|
||||
"Administrative group membership\n"
|
||||
"32-bit Hexadecimal value (e.g. 0xa1)\n")
|
||||
{
|
||||
struct interface *ifp = (struct interface *) vty->index;
|
||||
struct if_link_params *iflp = if_link_params_get (ifp);
|
||||
unsigned long value;
|
||||
|
||||
if (sscanf (argv[0], "0x%lx", &value) != 1)
|
||||
{
|
||||
vty_out (vty, "link_params_admin_grp: fscanf: %s%s",
|
||||
safe_strerror (errno), VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
/* Update Administrative Group if needed */
|
||||
link_param_cmd_set_uint32 (ifp, &iflp->admin_grp, LP_ADM_GRP, value);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (no_link_params_admin_grp,
|
||||
no_link_params_admin_grp_cmd,
|
||||
"no admin-grp",
|
||||
NO_STR
|
||||
"Disbale Administrative group membership on this interface\n")
|
||||
{
|
||||
struct interface *ifp = (struct interface *) vty->index;
|
||||
|
||||
/* Unset Admin Group */
|
||||
link_param_cmd_unset(ifp, LP_ADM_GRP);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/* RFC5392 & RFC5316: INTER-AS */
|
||||
DEFUN (link_params_inter_as,
|
||||
link_params_inter_as_cmd,
|
||||
"neighbor A.B.C.D as <1-4294967295>",
|
||||
"Configure remote ASBR information (Neighbor IP address and AS number)\n"
|
||||
"Remote IP address in dot decimal A.B.C.D\n"
|
||||
"Remote AS number\n"
|
||||
"AS number in the range <1-4294967295>\n")
|
||||
{
|
||||
|
||||
struct interface *ifp = (struct interface *) vty->index;
|
||||
struct if_link_params *iflp = if_link_params_get (ifp);
|
||||
struct in_addr addr;
|
||||
u_int32_t as;
|
||||
|
||||
if (!inet_aton (argv[0], &addr))
|
||||
{
|
||||
vty_out (vty, "Please specify Router-Addr by A.B.C.D%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
VTY_GET_ULONG("AS number", as, argv[1]);
|
||||
|
||||
/* Update Remote IP and Remote AS fields if needed */
|
||||
if (IS_PARAM_UNSET(iflp, LP_RMT_AS)
|
||||
|| iflp->rmt_as != as
|
||||
|| iflp->rmt_ip.s_addr != addr.s_addr)
|
||||
{
|
||||
|
||||
iflp->rmt_as = as;
|
||||
iflp->rmt_ip.s_addr = addr.s_addr;
|
||||
SET_PARAM(iflp, LP_RMT_AS);
|
||||
|
||||
/* force protocols to update LINK STATE due to parameters change */
|
||||
if (if_is_operative (ifp))
|
||||
zebra_interface_parameters_update (ifp);
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (no_link_params_inter_as,
|
||||
no_link_params_inter_as_cmd,
|
||||
"no neighbor",
|
||||
NO_STR
|
||||
"Remove Neighbor IP address and AS number for Inter-AS TE\n")
|
||||
{
|
||||
|
||||
struct interface *ifp = (struct interface *) vty->index;
|
||||
struct if_link_params *iflp = if_link_params_get (ifp);
|
||||
|
||||
/* Reset Remote IP and AS neighbor */
|
||||
iflp->rmt_as = 0;
|
||||
iflp->rmt_ip.s_addr = 0;
|
||||
UNSET_PARAM(iflp, LP_RMT_AS);
|
||||
|
||||
/* force protocols to update LINK STATE due to parameters change */
|
||||
if (if_is_operative (ifp))
|
||||
zebra_interface_parameters_update (ifp);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/* RFC7471: OSPF Traffic Engineering (TE) Metric extensions & draft-ietf-isis-metric-extensions-07.txt */
|
||||
DEFUN (link_params_delay,
|
||||
link_params_delay_cmd,
|
||||
"delay <0-16777215>",
|
||||
"Unidirectional Average Link Delay\n"
|
||||
"Average delay in micro-second as decimal (0...16777215)\n")
|
||||
{
|
||||
|
||||
struct interface *ifp = (struct interface *) vty->index;
|
||||
struct if_link_params *iflp = if_link_params_get (ifp);
|
||||
u_int32_t delay = 0, low = 0, high = 0;
|
||||
u_int8_t update = 0;
|
||||
|
||||
/* Get and Check new delay values */
|
||||
VTY_GET_ULONG("delay", delay, argv[0]);
|
||||
switch (argc)
|
||||
{
|
||||
case 1:
|
||||
/* Check new delay value against old Min and Max delays if set */
|
||||
if (IS_PARAM_SET(iflp, LP_MM_DELAY)
|
||||
&& (delay <= iflp->min_delay || delay >= iflp->max_delay))
|
||||
{
|
||||
vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s",
|
||||
iflp->min_delay, iflp->max_delay, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
/* Update delay if value is not set or change */
|
||||
if (IS_PARAM_UNSET(iflp, LP_DELAY)|| iflp->av_delay != delay)
|
||||
{
|
||||
iflp->av_delay = delay;
|
||||
SET_PARAM(iflp, LP_DELAY);
|
||||
update = 1;
|
||||
}
|
||||
/* Unset Min and Max delays if already set */
|
||||
if (IS_PARAM_SET(iflp, LP_MM_DELAY))
|
||||
{
|
||||
iflp->min_delay = 0;
|
||||
iflp->max_delay = 0;
|
||||
UNSET_PARAM(iflp, LP_MM_DELAY);
|
||||
update = 1;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
vty_out (vty, "You should specify both Minimum and Maximum delay with Average delay%s",
|
||||
VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
break;
|
||||
case 3:
|
||||
VTY_GET_ULONG("minimum delay", low, argv[1]);
|
||||
VTY_GET_ULONG("maximum delay", high, argv[2]);
|
||||
/* Check new delays value coherency */
|
||||
if (delay <= low || delay >= high)
|
||||
{
|
||||
vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s",
|
||||
low, high, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
/* Update Delays if needed */
|
||||
if (IS_PARAM_UNSET(iflp, LP_DELAY)
|
||||
|| IS_PARAM_UNSET(iflp, LP_MM_DELAY)
|
||||
|| iflp->av_delay != delay
|
||||
|| iflp->min_delay != low
|
||||
|| iflp->max_delay != high)
|
||||
{
|
||||
iflp->av_delay = delay;
|
||||
SET_PARAM(iflp, LP_DELAY);
|
||||
iflp->min_delay = low;
|
||||
iflp->max_delay = high;
|
||||
SET_PARAM(iflp, LP_MM_DELAY);
|
||||
update = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return CMD_WARNING;
|
||||
break;
|
||||
}
|
||||
|
||||
/* force protocols to update LINK STATE due to parameters change */
|
||||
if (update == 1 && if_is_operative (ifp))
|
||||
zebra_interface_parameters_update (ifp);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
ALIAS (link_params_delay,
|
||||
link_params_delay_mm_cmd,
|
||||
"delay <0-16777215> min <0-16777215> max <0-16777215>",
|
||||
"Unidirectional Average Link Delay (optionally Minimum and Maximum delays)\n"
|
||||
"Average delay in micro-second as decimal (0...16777215)\n"
|
||||
"Minimum delay\n"
|
||||
"Minimum delay in micro-second as decimal (0...16777215)\n"
|
||||
"Maximum delay\n"
|
||||
"Maximum delay in micro-second as decimal (0...16777215)\n")
|
||||
|
||||
DEFUN (no_link_params_delay,
|
||||
no_link_params_delay_cmd,
|
||||
"no delay",
|
||||
NO_STR
|
||||
"Disbale Unidirectional Average, Min & Max Link Delay on this interface\n")
|
||||
{
|
||||
struct interface *ifp = (struct interface *) vty->index;
|
||||
struct if_link_params *iflp = if_link_params_get (ifp);
|
||||
|
||||
/* Unset Delays */
|
||||
iflp->av_delay = 0;
|
||||
UNSET_PARAM(iflp, LP_DELAY);
|
||||
iflp->min_delay = 0;
|
||||
iflp->max_delay = 0;
|
||||
UNSET_PARAM(iflp, LP_MM_DELAY);
|
||||
|
||||
/* force protocols to update LINK STATE due to parameters change */
|
||||
if (if_is_operative (ifp))
|
||||
zebra_interface_parameters_update (ifp);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (link_params_delay_var,
|
||||
link_params_delay_var_cmd,
|
||||
"delay-variation <0-16777215>",
|
||||
"Unidirectional Link Delay Variation\n"
|
||||
"delay variation in micro-second as decimal (0...16777215)\n")
|
||||
{
|
||||
struct interface *ifp = (struct interface *) vty->index;
|
||||
struct if_link_params *iflp = if_link_params_get (ifp);
|
||||
u_int32_t value;
|
||||
|
||||
VTY_GET_ULONG("delay variation", value, argv[0]);
|
||||
|
||||
/* Update Delay Variation if needed */
|
||||
link_param_cmd_set_uint32 (ifp, &iflp->delay_var, LP_DELAY_VAR, value);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (no_link_params_delay_var,
|
||||
no_link_params_delay_var_cmd,
|
||||
"no delay-variation",
|
||||
NO_STR
|
||||
"Disbale Unidirectional Delay Variation on this interface\n")
|
||||
{
|
||||
struct interface *ifp = (struct interface *) vty->index;
|
||||
|
||||
/* Unset Delay Variation */
|
||||
link_param_cmd_unset(ifp, LP_DELAY_VAR);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (link_params_pkt_loss,
|
||||
link_params_pkt_loss_cmd,
|
||||
"packet-loss PERCENTAGE",
|
||||
"Unidirectional Link Packet Loss\n"
|
||||
"percentage of total traffic by 0.000003% step and less than 50.331642%\n")
|
||||
{
|
||||
struct interface *ifp = (struct interface *) vty->index;
|
||||
struct if_link_params *iflp = if_link_params_get (ifp);
|
||||
float fval;
|
||||
|
||||
if (sscanf (argv[0], "%g", &fval) != 1)
|
||||
{
|
||||
vty_out (vty, "link_params_pkt_loss: fscanf: %s%s", safe_strerror (errno),
|
||||
VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
if (fval > MAX_PKT_LOSS)
|
||||
fval = MAX_PKT_LOSS;
|
||||
|
||||
/* Update Packet Loss if needed */
|
||||
link_param_cmd_set_float (ifp, &iflp->pkt_loss, LP_PKT_LOSS, fval);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (no_link_params_pkt_loss,
|
||||
no_link_params_pkt_loss_cmd,
|
||||
"no packet-loss",
|
||||
NO_STR
|
||||
"Disbale Unidirectional Link Packet Loss on this interface\n")
|
||||
{
|
||||
struct interface *ifp = (struct interface *) vty->index;
|
||||
|
||||
/* Unset Packet Loss */
|
||||
link_param_cmd_unset(ifp, LP_PKT_LOSS);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (link_params_res_bw,
|
||||
link_params_res_bw_cmd,
|
||||
"res-bw BANDWIDTH",
|
||||
"Unidirectional Residual Bandwidth\n"
|
||||
"Bytes/second (IEEE floating point format)\n")
|
||||
{
|
||||
struct interface *ifp = (struct interface *) vty->index;
|
||||
struct if_link_params *iflp = if_link_params_get (ifp);
|
||||
float bw;
|
||||
|
||||
if (sscanf (argv[0], "%g", &bw) != 1)
|
||||
{
|
||||
vty_out (vty, "link_params_res_bw: fscanf: %s%s", safe_strerror (errno),
|
||||
VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
/* Check that bandwidth is not greater than maximum bandwidth parameter */
|
||||
if (bw > iflp->max_bw)
|
||||
{
|
||||
vty_out (vty,
|
||||
"Residual Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
|
||||
iflp->max_bw, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
/* Update Residual Bandwidth if needed */
|
||||
link_param_cmd_set_float (ifp, &iflp->res_bw, LP_RES_BW, bw);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (no_link_params_res_bw,
|
||||
no_link_params_res_bw_cmd,
|
||||
"no res-bw",
|
||||
NO_STR
|
||||
"Disbale Unidirectional Residual Bandwidth on this interface\n")
|
||||
{
|
||||
struct interface *ifp = (struct interface *) vty->index;
|
||||
|
||||
/* Unset Residual Bandwidth */
|
||||
link_param_cmd_unset(ifp, LP_RES_BW);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (link_params_ava_bw,
|
||||
link_params_ava_bw_cmd,
|
||||
"ava-bw BANDWIDTH",
|
||||
"Unidirectional Available Bandwidth\n"
|
||||
"Bytes/second (IEEE floating point format)\n")
|
||||
{
|
||||
struct interface *ifp = (struct interface *) vty->index;
|
||||
struct if_link_params *iflp = if_link_params_get (ifp);
|
||||
float bw;
|
||||
|
||||
if (sscanf (argv[0], "%g", &bw) != 1)
|
||||
{
|
||||
vty_out (vty, "link_params_ava_bw: fscanf: %s%s", safe_strerror (errno),
|
||||
VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
/* Check that bandwidth is not greater than maximum bandwidth parameter */
|
||||
if (bw > iflp->max_bw)
|
||||
{
|
||||
vty_out (vty,
|
||||
"Available Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
|
||||
iflp->max_bw, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
/* Update Residual Bandwidth if needed */
|
||||
link_param_cmd_set_float (ifp, &iflp->ava_bw, LP_AVA_BW, bw);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (no_link_params_ava_bw,
|
||||
no_link_params_ava_bw_cmd,
|
||||
"no ava-bw",
|
||||
NO_STR
|
||||
"Disbale Unidirectional Available Bandwidth on this interface\n")
|
||||
{
|
||||
struct interface *ifp = (struct interface *) vty->index;
|
||||
|
||||
/* Unset Available Bandwidth */
|
||||
link_param_cmd_unset(ifp, LP_AVA_BW);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (link_params_use_bw,
|
||||
link_params_use_bw_cmd,
|
||||
"use-bw BANDWIDTH",
|
||||
"Unidirectional Utilised Bandwidth\n"
|
||||
"Bytes/second (IEEE floating point format)\n")
|
||||
{
|
||||
struct interface *ifp = (struct interface *) vty->index;
|
||||
struct if_link_params *iflp = if_link_params_get (ifp);
|
||||
float bw;
|
||||
|
||||
if (sscanf (argv[0], "%g", &bw) != 1)
|
||||
{
|
||||
vty_out (vty, "link_params_use_bw: fscanf: %s%s", safe_strerror (errno),
|
||||
VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
/* Check that bandwidth is not greater than maximum bandwidth parameter */
|
||||
if (bw > iflp->max_bw)
|
||||
{
|
||||
vty_out (vty,
|
||||
"Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)%s",
|
||||
iflp->max_bw, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
/* Update Utilized Bandwidth if needed */
|
||||
link_param_cmd_set_float (ifp, &iflp->use_bw, LP_USE_BW, bw);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (no_link_params_use_bw,
|
||||
no_link_params_use_bw_cmd,
|
||||
"no use-bw",
|
||||
NO_STR
|
||||
"Disbale Unidirectional Utilised Bandwidth on this interface\n")
|
||||
{
|
||||
struct interface *ifp = (struct interface *) vty->index;
|
||||
|
||||
/* Unset Utilised Bandwidth */
|
||||
link_param_cmd_unset(ifp, LP_USE_BW);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
ip_address_install (struct vty *vty, struct interface *ifp,
|
||||
const char *addr_str, const char *peer_str,
|
||||
@ -2054,6 +2787,58 @@ DEFUN (no_ipv6_address,
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
static int
|
||||
link_params_config_write (struct vty *vty, struct interface *ifp)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ((ifp == NULL) || !HAS_LINK_PARAMS(ifp))
|
||||
return -1;
|
||||
|
||||
struct if_link_params *iflp = ifp->link_params;
|
||||
|
||||
vty_out (vty, " link-params%s", VTY_NEWLINE);
|
||||
vty_out(vty, " enable%s", VTY_NEWLINE);
|
||||
if (IS_PARAM_SET(iflp, LP_TE))
|
||||
vty_out(vty, " metric %u%s",iflp->te_metric, VTY_NEWLINE);
|
||||
if (IS_PARAM_SET(iflp, LP_MAX_BW))
|
||||
vty_out(vty, " max-bw %g%s", iflp->max_bw, VTY_NEWLINE);
|
||||
if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW))
|
||||
vty_out(vty, " max-rsv-bw %g%s", iflp->max_rsv_bw, VTY_NEWLINE);
|
||||
if (IS_PARAM_SET(iflp, LP_UNRSV_BW))
|
||||
{
|
||||
for (i = 0; i < 8; i++)
|
||||
vty_out(vty, " unrsv-bw %d %g%s",
|
||||
i, iflp->unrsv_bw[i], VTY_NEWLINE);
|
||||
}
|
||||
if (IS_PARAM_SET(iflp, LP_ADM_GRP))
|
||||
vty_out(vty, " admin-grp %u%s", iflp->admin_grp, VTY_NEWLINE);
|
||||
if (IS_PARAM_SET(iflp, LP_DELAY))
|
||||
{
|
||||
vty_out(vty, " delay %u", iflp->av_delay);
|
||||
if (IS_PARAM_SET(iflp, LP_MM_DELAY))
|
||||
{
|
||||
vty_out(vty, " min %u", iflp->min_delay);
|
||||
vty_out(vty, " max %u", iflp->max_delay);
|
||||
}
|
||||
vty_out(vty, "%s", VTY_NEWLINE);
|
||||
}
|
||||
if (IS_PARAM_SET(iflp, LP_DELAY_VAR))
|
||||
vty_out(vty, " delay-variation %u%s", iflp->delay_var, VTY_NEWLINE);
|
||||
if (IS_PARAM_SET(iflp, LP_PKT_LOSS))
|
||||
vty_out(vty, " packet-loss %g%s", iflp->pkt_loss, VTY_NEWLINE);
|
||||
if (IS_PARAM_SET(iflp, LP_AVA_BW))
|
||||
vty_out(vty, " ava-bw %g%s", iflp->ava_bw, VTY_NEWLINE);
|
||||
if (IS_PARAM_SET(iflp, LP_RES_BW))
|
||||
vty_out(vty, " res-bw %g%s", iflp->res_bw, VTY_NEWLINE);
|
||||
if (IS_PARAM_SET(iflp, LP_USE_BW))
|
||||
vty_out(vty, " use-bw %g%s", iflp->use_bw, VTY_NEWLINE);
|
||||
if (IS_PARAM_SET(iflp, LP_RMT_AS))
|
||||
vty_out(vty, " neighbor %s as %u%s", inet_ntoa(iflp->rmt_ip),
|
||||
iflp->rmt_as, VTY_NEWLINE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
if_config_write (struct vty *vty)
|
||||
{
|
||||
@ -2134,6 +2919,8 @@ if_config_write (struct vty *vty)
|
||||
irdp_config_write (vty, ifp);
|
||||
#endif /* IRDP */
|
||||
|
||||
link_params_config_write (vty, ifp);
|
||||
|
||||
vty_out (vty, "!%s", VTY_NEWLINE);
|
||||
}
|
||||
return 0;
|
||||
@ -2166,6 +2953,7 @@ zebra_if_init (void)
|
||||
|
||||
/* Install configuration write function. */
|
||||
install_node (&interface_node, if_config_write);
|
||||
install_node (&link_params_node, NULL);
|
||||
install_node (&vrf_node, vrf_config_write);
|
||||
|
||||
install_element (VIEW_NODE, &show_interface_cmd);
|
||||
@ -2209,9 +2997,26 @@ zebra_if_init (void)
|
||||
install_element (INTERFACE_NODE, &ip_address_label_cmd);
|
||||
install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
|
||||
#endif /* HAVE_NETLINK */
|
||||
install_element(INTERFACE_NODE, &link_params_cmd);
|
||||
install_default(LINK_PARAMS_NODE);
|
||||
install_element(LINK_PARAMS_NODE, &link_params_enable_cmd);
|
||||
install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd);
|
||||
install_element(LINK_PARAMS_NODE, &link_params_metric_cmd);
|
||||
install_element(LINK_PARAMS_NODE, &link_params_maxbw_cmd);
|
||||
install_element(LINK_PARAMS_NODE, &link_params_max_rsv_bw_cmd);
|
||||
install_element(LINK_PARAMS_NODE, &link_params_unrsv_bw_cmd);
|
||||
install_element(LINK_PARAMS_NODE, &link_params_admin_grp_cmd);
|
||||
install_element(LINK_PARAMS_NODE, &link_params_inter_as_cmd);
|
||||
install_element(LINK_PARAMS_NODE, &no_link_params_inter_as_cmd);
|
||||
install_element(LINK_PARAMS_NODE, &link_params_delay_cmd);
|
||||
install_element(LINK_PARAMS_NODE, &link_params_delay_mm_cmd);
|
||||
install_element(LINK_PARAMS_NODE, &link_params_delay_var_cmd);
|
||||
install_element(LINK_PARAMS_NODE, &link_params_pkt_loss_cmd);
|
||||
install_element(LINK_PARAMS_NODE, &link_params_ava_bw_cmd);
|
||||
install_element(LINK_PARAMS_NODE, &link_params_res_bw_cmd);
|
||||
install_element(LINK_PARAMS_NODE, &link_params_use_bw_cmd);
|
||||
|
||||
install_element (CONFIG_NODE, &zebra_vrf_cmd);
|
||||
install_element (CONFIG_NODE, &no_vrf_cmd);
|
||||
install_default (VRF_NODE);
|
||||
|
||||
}
|
||||
|
@ -385,8 +385,10 @@ zebra_interface_up_update (struct interface *ifp)
|
||||
|
||||
if (ifp->ptm_status || !ifp->ptm_enable) {
|
||||
for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
|
||||
if (client->ifinfo)
|
||||
{
|
||||
zsend_interface_update (ZEBRA_INTERFACE_UP, client, ifp);
|
||||
zsend_interface_link_params (client, ifp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -418,9 +420,11 @@ zebra_interface_add_update (struct interface *ifp)
|
||||
zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADD %s[%d]", ifp->name, ifp->vrf_id);
|
||||
|
||||
for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
|
||||
if (client->ifinfo)
|
||||
{
|
||||
client->ifadd_cnt++;
|
||||
zsend_interface_add (client, ifp);
|
||||
zsend_interface_link_params (client, ifp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -797,3 +801,18 @@ zebra_import_table_rm_update ()
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Interface parameters update */
|
||||
void
|
||||
zebra_interface_parameters_update (struct interface *ifp)
|
||||
{
|
||||
struct listnode *node, *nnode;
|
||||
struct zserv *client;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_EVENT)
|
||||
zlog_debug ("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s", ifp->name);
|
||||
|
||||
for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
|
||||
if (client->ifinfo)
|
||||
zsend_interface_link_params (client, ifp);
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ extern void zebra_interface_address_add_update (struct interface *,
|
||||
struct connected *);
|
||||
extern void zebra_interface_address_delete_update (struct interface *,
|
||||
struct connected *c);
|
||||
extern void zebra_interface_parameters_update (struct interface *);
|
||||
extern void zebra_interface_vrf_update_del (struct interface *, vrf_id_t new_vrf_id);
|
||||
extern void zebra_interface_vrf_update_add (struct interface *, vrf_id_t old_vrf_id);
|
||||
|
||||
|
@ -60,6 +60,10 @@ void zebra_interface_address_delete_update (struct interface *a,
|
||||
struct connected *b)
|
||||
{ return; }
|
||||
|
||||
/* Interface parameters update */
|
||||
void zebra_interface_parameters_update (struct interface *ifp)
|
||||
{ return; };
|
||||
|
||||
void zebra_interface_vrf_update_del (struct interface *a, vrf_id_t new_vrf_id)
|
||||
{ return; }
|
||||
|
||||
|
@ -165,6 +165,16 @@ zserv_encode_interface (struct stream *s, struct interface *ifp)
|
||||
if (ifp->hw_addr_len)
|
||||
stream_put (s, ifp->hw_addr, ifp->hw_addr_len);
|
||||
|
||||
zlog_info("Try to set TE Link Param");
|
||||
/* Then, Traffic Engineering parameters if any */
|
||||
if (HAS_LINK_PARAMS(ifp) && IS_LINK_PARAMS_SET(ifp->link_params))
|
||||
{
|
||||
stream_putc (s, 1);
|
||||
zebra_interface_link_params_write (s, ifp);
|
||||
}
|
||||
else
|
||||
stream_putc (s, 0);
|
||||
|
||||
/* Write packet size. */
|
||||
stream_putw_at (s, 0, stream_get_endp (s));
|
||||
}
|
||||
@ -252,6 +262,35 @@ zsend_vrf_delete (struct zserv *client, struct zebra_vrf *zvrf)
|
||||
return zebra_server_send_message (client);
|
||||
}
|
||||
|
||||
int
|
||||
zsend_interface_link_params (struct zserv *client, struct interface *ifp)
|
||||
{
|
||||
struct stream *s;
|
||||
|
||||
/* Check this client need interface information. */
|
||||
if (! client->ifinfo)
|
||||
return 0;
|
||||
|
||||
if (!ifp->link_params)
|
||||
return 0;
|
||||
s = client->obuf;
|
||||
stream_reset (s);
|
||||
|
||||
zserv_create_header (s, ZEBRA_INTERFACE_LINK_PARAMS, ifp->vrf_id);
|
||||
|
||||
/* Add Interface Index */
|
||||
stream_putl (s, ifp->ifindex);
|
||||
|
||||
/* Then TE Link Parameters */
|
||||
if (zebra_interface_link_params_write (s, ifp) == 0)
|
||||
return 0;
|
||||
|
||||
/* Write packet size. */
|
||||
stream_putw_at (s, 0, stream_get_endp (s));
|
||||
|
||||
return zebra_server_send_message (client);
|
||||
}
|
||||
|
||||
/* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or
|
||||
* ZEBRA_INTERFACE_ADDRESS_DELETE to the client.
|
||||
*
|
||||
|
@ -165,6 +165,8 @@ extern int zsend_router_id_update (struct zserv *, struct prefix *,
|
||||
extern int zsend_interface_vrf_update (struct zserv *, struct interface *,
|
||||
vrf_id_t);
|
||||
|
||||
extern int zsend_interface_link_params (struct zserv *, struct interface *);
|
||||
|
||||
extern pid_t pid;
|
||||
|
||||
extern void zserv_create_header(struct stream *s, uint16_t cmd, vrf_id_t vrf_id);
|
||||
|
Loading…
Reference in New Issue
Block a user