1610
1706
sset_destroy(&devnames);
1614
1710
alloc_ofp_port(struct ofproto *ofproto, const char *netdev_name)
1617
uint16_t end_port_no = ofproto->alloc_port_no;
1619
ofp_port = simap_get(&ofproto->ofp_requests, netdev_name);
1620
ofp_port = ofp_port ? ofp_port : OFPP_NONE;
1622
if (ofp_port >= ofproto->max_ports
1623
|| bitmap_is_set(ofproto->ofp_port_ids, ofp_port)) {
1712
uint16_t max_ports = ofp_to_u16(ofproto->max_ports);
1715
port_idx = simap_get(&ofproto->ofp_requests, netdev_name);
1717
port_idx = UINT16_MAX;
1720
if (port_idx >= max_ports
1721
|| bitmap_is_set(ofproto->ofp_port_ids, port_idx)) {
1722
uint16_t end_port_no = ofp_to_u16(ofproto->alloc_port_no);
1723
uint16_t alloc_port_no = end_port_no;
1624
1725
/* Search for a free OpenFlow port number. We try not to
1625
1726
* immediately reuse them to prevent problems due to old
1628
if (++ofproto->alloc_port_no >= ofproto->max_ports) {
1629
ofproto->alloc_port_no = 0;
1729
if (++alloc_port_no >= max_ports) {
1631
if (!bitmap_is_set(ofproto->ofp_port_ids,
1632
ofproto->alloc_port_no)) {
1633
ofp_port = ofproto->alloc_port_no;
1732
if (!bitmap_is_set(ofproto->ofp_port_ids, alloc_port_no)) {
1733
port_idx = alloc_port_no;
1734
ofproto->alloc_port_no = u16_to_ofp(alloc_port_no);
1636
if (ofproto->alloc_port_no == end_port_no) {
1737
if (alloc_port_no == end_port_no) {
1637
1738
return OFPP_NONE;
1641
bitmap_set1(ofproto->ofp_port_ids, ofp_port);
1742
bitmap_set1(ofproto->ofp_port_ids, port_idx);
1743
return u16_to_ofp(port_idx);
1646
dealloc_ofp_port(const struct ofproto *ofproto, uint16_t ofp_port)
1747
dealloc_ofp_port(const struct ofproto *ofproto, ofp_port_t ofp_port)
1648
if (ofp_port < ofproto->max_ports) {
1649
bitmap_set0(ofproto->ofp_port_ids, ofp_port);
1749
if (ofp_to_u16(ofp_port) < ofp_to_u16(ofproto->max_ports)) {
1750
bitmap_set0(ofproto->ofp_port_ids, ofp_to_u16(ofp_port));
2272
2379
reject_slave_controller(struct ofconn *ofconn)
2274
2381
if (ofconn_get_type(ofconn) == OFCONN_PRIMARY
2275
&& ofconn_get_role(ofconn) == NX_ROLE_SLAVE) {
2382
&& ofconn_get_role(ofconn) == OFPCR12_ROLE_SLAVE) {
2276
2383
return OFPERR_OFPBRC_EPERM;
2389
/* Finds the OFPACT_METER action, if any, in the 'ofpacts_len' bytes of
2390
* 'ofpacts'. If found, returns its meter ID; if not, returns 0.
2392
* This function relies on the order of 'ofpacts' being correct (as checked by
2393
* ofpacts_verify()). */
2395
find_meter(const struct ofpact ofpacts[], size_t ofpacts_len)
2397
const struct ofpact *a;
2399
OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
2400
enum ovs_instruction_type inst;
2402
inst = ovs_instruction_type_from_ofpact_type(a->type);
2403
if (a->type == OFPACT_METER) {
2404
return ofpact_get_METER(a)->meter_id;
2405
} else if (inst > OVSINST_OFPIT13_METER) {
2413
/* Checks that the 'ofpacts_len' bytes of actions in 'ofpacts' are appropriate
2414
* for a packet with the prerequisites satisfied by 'flow' in table 'table_id'.
2415
* 'flow' may be temporarily modified, but is restored at return.
2418
ofproto_check_ofpacts(struct ofproto *ofproto,
2419
const struct ofpact ofpacts[], size_t ofpacts_len,
2420
struct flow *flow, uint8_t table_id)
2425
error = ofpacts_check(ofpacts, ofpacts_len, flow, ofproto->max_ports,
2431
mid = find_meter(ofpacts, ofpacts_len);
2432
if (mid && ofproto_get_provider_meter_id(ofproto, mid) == UINT32_MAX) {
2433
return OFPERR_OFPMMFC_INVALID_METER;
2282
2438
static enum ofperr
2283
2439
handle_packet_out(struct ofconn *ofconn, const struct ofp_header *oh)
2843
3089
ofproto->ofproto_class->get_netflow_ids(ofproto, engine_type, engine_id);
2846
/* Checks the fault status of CFM for 'ofp_port' within 'ofproto'. Returns a
2847
* bitmask of 'cfm_fault_reason's to indicate a CFM fault (generally
2848
* indicating a connectivity problem). Returns zero if CFM is not faulted,
2849
* and -1 if CFM is not enabled on 'ofp_port'. */
2851
ofproto_port_get_cfm_fault(const struct ofproto *ofproto, uint16_t ofp_port)
2853
struct ofport *ofport = ofproto_get_port(ofproto, ofp_port);
2854
return (ofport && ofproto->ofproto_class->get_cfm_fault
2855
? ofproto->ofproto_class->get_cfm_fault(ofport)
2859
/* Checks the operational status reported by the remote CFM endpoint of
2860
* 'ofp_port' Returns 1 if operationally up, 0 if operationally down, and -1
2861
* if CFM is not enabled on 'ofp_port' or does not support operational status.
2864
ofproto_port_get_cfm_opup(const struct ofproto *ofproto, uint16_t ofp_port)
2866
struct ofport *ofport = ofproto_get_port(ofproto, ofp_port);
2867
return (ofport && ofproto->ofproto_class->get_cfm_opup
2868
? ofproto->ofproto_class->get_cfm_opup(ofport)
2872
/* Gets the MPIDs of the remote maintenance points broadcasting to 'ofp_port'
2873
* within 'ofproto'. Populates 'rmps' with an array of MPIDs owned by
2874
* 'ofproto', and 'n_rmps' with the number of MPIDs in 'rmps'. Returns a
2875
* number less than 0 if CFM is not enabled on 'ofp_port'. */
2877
ofproto_port_get_cfm_remote_mpids(const struct ofproto *ofproto,
2878
uint16_t ofp_port, const uint64_t **rmps,
2881
struct ofport *ofport = ofproto_get_port(ofproto, ofp_port);
2885
return (ofport && ofproto->ofproto_class->get_cfm_remote_mpids
2886
? ofproto->ofproto_class->get_cfm_remote_mpids(ofport, rmps,
2891
/* Checks the health of the CFM for 'ofp_port' within 'ofproto'. Returns an
2892
* integer value between 0 and 100 to indicate the health of the port as a
2893
* percentage which is the average of cfm health of all the remote_mpids or
2894
* returns -1 if CFM is not enabled on 'ofport'. */
2896
ofproto_port_get_cfm_health(const struct ofproto *ofproto, uint16_t ofp_port)
2898
struct ofport *ofport = ofproto_get_port(ofproto, ofp_port);
2899
return (ofport && ofproto->ofproto_class->get_cfm_health
2900
? ofproto->ofproto_class->get_cfm_health(ofport)
3092
/* Checks the status of CFM configured on 'ofp_port' within 'ofproto'. Returns
3093
* true if the port's CFM status was successfully stored into '*status'.
3094
* Returns false if the port did not have CFM configured, in which case
3095
* '*status' is indeterminate.
3097
* The caller must provide and owns '*status', and must free 'status->rmps'. */
3099
ofproto_port_get_cfm_status(const struct ofproto *ofproto, ofp_port_t ofp_port,
3100
struct ofproto_cfm_status *status)
3102
struct ofport *ofport = ofproto_get_port(ofproto, ofp_port);
3104
&& ofproto->ofproto_class->get_cfm_status
3105
&& ofproto->ofproto_class->get_cfm_status(ofport, status));
2904
3108
static enum ofperr
3576
3794
static enum ofperr
3577
3795
handle_role_request(struct ofconn *ofconn, const struct ofp_header *oh)
3579
struct ofputil_role_request rr;
3797
struct ofputil_role_request request;
3798
struct ofputil_role_request reply;
3580
3799
struct ofpbuf *buf;
3582
3800
enum ofperr error;
3584
error = ofputil_decode_role_message(oh, &rr);
3802
error = ofputil_decode_role_message(oh, &request);
3589
if (rr.request_current_role_only) {
3590
role = ofconn_get_role(ofconn); /* NX_ROLE_* */
3596
if (ofconn_get_role(ofconn) != role
3597
&& ofconn_has_pending_opgroups(ofconn)) {
3598
return OFPROTO_POSTPONE;
3601
if (rr.have_generation_id) {
3602
if (!ofconn_set_master_election_id(ofconn, rr.generation_id)) {
3603
return OFPERR_OFPRRFC_STALE;
3607
ofconn_set_role(ofconn, role);
3610
buf = ofputil_encode_role_reply(oh, role);
3807
if (request.role != OFPCR12_ROLE_NOCHANGE) {
3808
if (ofconn_get_role(ofconn) != request.role
3809
&& ofconn_has_pending_opgroups(ofconn)) {
3810
return OFPROTO_POSTPONE;
3813
if (request.have_generation_id
3814
&& !ofconn_set_master_election_id(ofconn, request.generation_id)) {
3815
return OFPERR_OFPRRFC_STALE;
3818
ofconn_set_role(ofconn, request.role);
3821
reply.role = ofconn_get_role(ofconn);
3822
reply.have_generation_id = ofconn_get_master_election_id(
3823
ofconn, &reply.generation_id);
3824
buf = ofputil_encode_role_reply(oh, &reply);
3611
3825
ofconn_send_reply(ofconn, buf);
4197
/* Meters implementation.
4199
* Meter table entry, indexed by the OpenFlow meter_id.
4200
* These are always dynamically allocated to allocate enough space for
4202
* 'created' is used to compute the duration for meter stats.
4203
* 'list rules' is needed so that we can delete the dependent rules when the
4204
* meter table entry is deleted.
4205
* 'provider_meter_id' is for the provider's private use.
4208
long long int created; /* Time created. */
4209
struct list rules; /* List of "struct rule_dpif"s. */
4210
ofproto_meter_id provider_meter_id;
4211
uint16_t flags; /* Meter flags. */
4212
uint16_t n_bands; /* Number of meter bands. */
4213
struct ofputil_meter_band *bands;
4217
* This is used in instruction validation at flow set-up time,
4218
* as flows may not use non-existing meters.
4219
* This is also used by ofproto-providers to translate OpenFlow meter_ids
4220
* in METER instructions to the corresponding provider meter IDs.
4221
* Return value of UINT32_MAX signifies an invalid meter.
4224
ofproto_get_provider_meter_id(const struct ofproto * ofproto,
4225
uint32_t of_meter_id)
4227
if (of_meter_id && of_meter_id <= ofproto->meter_features.max_meters) {
4228
const struct meter *meter = ofproto->meters[of_meter_id];
4230
return meter->provider_meter_id.uint32;
4237
meter_update(struct meter *meter, const struct ofputil_meter_config *config)
4241
meter->flags = config->flags;
4242
meter->n_bands = config->n_bands;
4243
meter->bands = xmemdup(config->bands,
4244
config->n_bands * sizeof *meter->bands);
4247
static struct meter *
4248
meter_create(const struct ofputil_meter_config *config,
4249
ofproto_meter_id provider_meter_id)
4251
struct meter *meter;
4253
meter = xzalloc(sizeof *meter);
4254
meter->provider_meter_id = provider_meter_id;
4255
meter->created = time_msec();
4256
list_init(&meter->rules);
4258
meter_update(meter, config);
4264
meter_delete(struct ofproto *ofproto, uint32_t first, uint32_t last)
4267
for (mid = first; mid <= last; ++mid) {
4268
struct meter *meter = ofproto->meters[mid];
4270
ofproto->meters[mid] = NULL;
4271
ofproto->ofproto_class->meter_del(ofproto,
4272
meter->provider_meter_id);
4280
handle_add_meter(struct ofproto *ofproto, struct ofputil_meter_mod *mm)
4282
ofproto_meter_id provider_meter_id = { UINT32_MAX };
4283
struct meter **meterp = &ofproto->meters[mm->meter.meter_id];
4287
return OFPERR_OFPMMFC_METER_EXISTS;
4290
error = ofproto->ofproto_class->meter_set(ofproto, &provider_meter_id,
4293
ovs_assert(provider_meter_id.uint32 != UINT32_MAX);
4294
*meterp = meter_create(&mm->meter, provider_meter_id);
4300
handle_modify_meter(struct ofproto *ofproto, struct ofputil_meter_mod *mm)
4302
struct meter *meter = ofproto->meters[mm->meter.meter_id];
4306
return OFPERR_OFPMMFC_UNKNOWN_METER;
4309
error = ofproto->ofproto_class->meter_set(ofproto,
4310
&meter->provider_meter_id,
4312
ovs_assert(meter->provider_meter_id.uint32 != UINT32_MAX);
4314
meter_update(meter, &mm->meter);
4320
handle_delete_meter(struct ofconn *ofconn, const struct ofp_header *oh,
4321
struct ofputil_meter_mod *mm)
4323
struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
4324
uint32_t meter_id = mm->meter.meter_id;
4325
uint32_t first, last;
4328
if (meter_id == OFPM13_ALL) {
4330
last = ofproto->meter_features.max_meters;
4332
if (!meter_id || meter_id > ofproto->meter_features.max_meters) {
4335
first = last = meter_id;
4338
/* First delete the rules that use this meter. If any of those rules are
4339
* currently being modified, postpone the whole operation until later. */
4341
for (meter_id = first; meter_id <= last; ++meter_id) {
4342
struct meter *meter = ofproto->meters[meter_id];
4343
if (meter && !list_is_empty(&meter->rules)) {
4346
LIST_FOR_EACH (rule, meter_list_node, &meter->rules) {
4347
if (rule->pending) {
4348
return OFPROTO_POSTPONE;
4350
list_push_back(&rules, &rule->ofproto_node);
4354
if (!list_is_empty(&rules)) {
4355
delete_flows__(ofproto, ofconn, oh, &rules, OFPRR_METER_DELETE);
4358
/* Delete the meters. */
4359
meter_delete(ofproto, first, last);
4365
handle_meter_mod(struct ofconn *ofconn, const struct ofp_header *oh)
4367
struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
4368
struct ofputil_meter_mod mm;
4369
uint64_t bands_stub[256 / 8];
4370
struct ofpbuf bands;
4374
error = reject_slave_controller(ofconn);
4379
ofpbuf_use_stub(&bands, bands_stub, sizeof bands_stub);
4381
error = ofputil_decode_meter_mod(oh, &mm, &bands);
4383
goto exit_free_bands;
4386
meter_id = mm.meter.meter_id;
4388
if (mm.command != OFPMC13_DELETE) {
4389
/* Fails also when meters are not implemented by the provider. */
4390
if (!meter_id || meter_id > ofproto->meter_features.max_meters) {
4391
error = OFPERR_OFPMMFC_INVALID_METER;
4392
goto exit_free_bands;
4394
if (mm.meter.n_bands > ofproto->meter_features.max_bands) {
4395
error = OFPERR_OFPMMFC_OUT_OF_BANDS;
4396
goto exit_free_bands;
4400
switch (mm.command) {
4402
error = handle_add_meter(ofproto, &mm);
4405
case OFPMC13_MODIFY:
4406
error = handle_modify_meter(ofproto, &mm);
4409
case OFPMC13_DELETE:
4410
error = handle_delete_meter(ofconn, oh, &mm);
4414
error = OFPERR_OFPMMFC_BAD_COMMAND;
4419
ofpbuf_uninit(&bands);
4424
handle_meter_features_request(struct ofconn *ofconn,
4425
const struct ofp_header *request)
4427
struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
4428
struct ofputil_meter_features features;
4431
if (ofproto->ofproto_class->meter_get_features) {
4432
ofproto->ofproto_class->meter_get_features(ofproto, &features);
4434
memset(&features, 0, sizeof features);
4436
b = ofputil_encode_meter_features_reply(&features, request);
4438
ofconn_send_reply(ofconn, b);
4443
handle_meter_request(struct ofconn *ofconn, const struct ofp_header *request,
4446
struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
4447
struct list replies;
4448
uint64_t bands_stub[256 / 8];
4449
struct ofpbuf bands;
4450
uint32_t meter_id, first, last;
4452
ofputil_decode_meter_request(request, &meter_id);
4454
if (meter_id == OFPM13_ALL) {
4456
last = ofproto->meter_features.max_meters;
4458
if (!meter_id || meter_id > ofproto->meter_features.max_meters ||
4459
!ofproto->meters[meter_id]) {
4460
return OFPERR_OFPMMFC_UNKNOWN_METER;
4462
first = last = meter_id;
4465
ofpbuf_use_stub(&bands, bands_stub, sizeof bands_stub);
4466
ofpmp_init(&replies, request);
4468
for (meter_id = first; meter_id <= last; ++meter_id) {
4469
struct meter *meter = ofproto->meters[meter_id];
4471
continue; /* Skip non-existing meters. */
4473
if (type == OFPTYPE_METER_STATS_REQUEST) {
4474
struct ofputil_meter_stats stats;
4476
stats.meter_id = meter_id;
4478
/* Provider sets the packet and byte counts, we do the rest. */
4479
stats.flow_count = list_size(&meter->rules);
4480
calc_duration(meter->created, time_msec(),
4481
&stats.duration_sec, &stats.duration_nsec);
4482
stats.n_bands = meter->n_bands;
4483
ofpbuf_clear(&bands);
4485
= ofpbuf_put_uninit(&bands,
4486
meter->n_bands * sizeof *stats.bands);
4488
if (!ofproto->ofproto_class->meter_get(ofproto,
4489
meter->provider_meter_id,
4491
ofputil_append_meter_stats(&replies, &stats);
4493
} else { /* type == OFPTYPE_METER_CONFIG_REQUEST */
4494
struct ofputil_meter_config config;
4496
config.meter_id = meter_id;
4497
config.flags = meter->flags;
4498
config.n_bands = meter->n_bands;
4499
config.bands = meter->bands;
4500
ofputil_append_meter_config(&replies, &config);
4504
ofconn_send_replies(ofconn, &replies);
4505
ofpbuf_uninit(&bands);
3983
4509
static enum ofperr
3984
4510
handle_openflow__(struct ofconn *ofconn, const struct ofpbuf *msg)