ExprMatrix *expr_matrix_simplify_sum(const std::list<ExpressionRename *>& list) { bool is_matrix = list.front()->get_type() == EXPRESSION_TYPE_MATRIX; if (!is_matrix) { throw 3; } int m = ((ExprMatrix *) list.front())->get_m(); int n = ((ExprMatrix *) list.front())->get_n(); ExprMatrix *matrix = new ExprMatrix { m, n }; for (int i = 0; i < m * n; i++) matrix->elems[i] = new ExprAddition { }; const auto end = list.end(); for (auto it = list.begin(); it != end; ++it) { if ((*it)->get_type() != EXPRESSION_TYPE_MATRIX) throw 1; ExprMatrix *mat = (ExprMatrix *) (*it); if (mat->get_m() != m || mat->get_n() != n) throw 2; for (int i = 0; i < m * n; i++) ((ExprAddition *) matrix->elems[i])->add(mat->elems[i]->clone()); } if (m != 1 || n != 1) return (ExprMatrix *) expr_simplify(matrix); return matrix; }
/** * derv_ExprExt : calcule la dérivé première d'une expression * @param expr l'expression pour laquel calculer la dérivé * @return l'expresssion dérivé */ extern Expr * derv_ExprExt(Expr * expr) { switch (expr->type) { case ELEMENT: switch (expr->u.Element.elType) { case VAL: return new_Element(0, 0, INT, VAL); case VAR: return new_Element(expr->u.Element.power, expr->u.Element.power - 1, INT, (expr->u.Element.power - 1) == 0 ? VAL : VALVAR); case VALVAR: return new_Element( expr->u.Element.power * expr->u.Element.value, expr->u.Element.power - 1, expr->u.Element.typecst == REEL ? REEL : INT, (expr->u.Element.power - 1) == 0 ? VAL : VALVAR); } case OPBINAIRE: switch (expr->u.OpBinaire.operateur) { case PLUS: return new_OpBinaire(derv_ExprExt(expr->u.OpBinaire.left), '+', derv_ExprExt(expr->u.OpBinaire.rigth)); case MULT: return new_OpBinaire( new_Par(new_OpBinaire(new_Par(derv_ExprExt(expr->u.OpBinaire.left)), '*', expr->u.OpBinaire.rigth)), '+', new_Par(new_OpBinaire(expr->u.OpBinaire.left, '*', new_Par(derv_ExprExt(expr->u.OpBinaire.rigth))))); } case FUNCT: { Expr* identFunc = exprList_get(expr->u.Func.name); if (identFunc == NULL) { fprintf(stderr, "ERROR dans la simplification, l'identifiant de la fonction [%s] n'existe pas!\n", expr->u.Func.name); exit(EXIT_FAILURE); } Expr* simplified = expr_simplify(identFunc); Expr* derivated = expr_derivate(simplified, expr->u.Func.derivative); Expr* paramExpr = expr_simplify(expr->u.Func.child); identFunc = expr_replaceVariable(derivated, paramExpr); return derv_ExprExt(identFunc); } case PAR: return derv_ExprExt(expr->u.Par.single); } }
ExpressionRename* ExprMatrix::simplify(const SimplificationRules& rules) { for (int i=0;i<m*n;i++) elems[i] = expr_simplify(elems[i], rules); return this; }
static void test_parse_actions(const char *input) { struct shash symtab; struct hmap dhcp_opts; struct hmap dhcpv6_opts; struct hmap nd_ra_opts; struct simap ports; create_symtab(&symtab); create_gen_opts(&dhcp_opts, &dhcpv6_opts, &nd_ra_opts); /* Initialize group ids. */ struct ovn_extend_table group_table; ovn_extend_table_init(&group_table); /* Initialize meter ids for QoS. */ struct ovn_extend_table meter_table; ovn_extend_table_init(&meter_table); simap_init(&ports); simap_put(&ports, "eth0", 5); simap_put(&ports, "eth1", 6); simap_put(&ports, "LOCAL", ofp_to_u16(OFPP_LOCAL)); struct ofpbuf ovnacts; struct expr *prereqs; char *error; puts(input); ofpbuf_init(&ovnacts, 0); const struct ovnact_parse_params pp = { .symtab = &symtab, .dhcp_opts = &dhcp_opts, .dhcpv6_opts = &dhcpv6_opts, .nd_ra_opts = &nd_ra_opts, .n_tables = 24, .cur_ltable = 10, }; error = ovnacts_parse_string(input, &pp, &ovnacts, &prereqs); if (!error) { /* Convert the parsed representation back to a string and print it, * if it's different from the input. */ struct ds ovnacts_s = DS_EMPTY_INITIALIZER; ovnacts_format(ovnacts.data, ovnacts.size, &ovnacts_s); if (strcmp(input, ds_cstr(&ovnacts_s))) { printf(" formats as %s\n", ds_cstr(&ovnacts_s)); } /* Encode the actions into OpenFlow and print. */ const struct ovnact_encode_params ep = { .lookup_port = lookup_port_cb, .aux = &ports, .is_switch = true, .group_table = &group_table, .meter_table = &meter_table, .pipeline = OVNACT_P_INGRESS, .ingress_ptable = 8, .egress_ptable = 40, .output_ptable = 64, .mac_bind_ptable = 65, }; struct ofpbuf ofpacts; ofpbuf_init(&ofpacts, 0); ovnacts_encode(ovnacts.data, ovnacts.size, &ep, &ofpacts); struct ds ofpacts_s = DS_EMPTY_INITIALIZER; struct ofpact_format_params fp = { .s = &ofpacts_s }; ofpacts_format(ofpacts.data, ofpacts.size, &fp); printf(" encodes as %s\n", ds_cstr(&ofpacts_s)); ds_destroy(&ofpacts_s); ofpbuf_uninit(&ofpacts); /* Print prerequisites if any. */ if (prereqs) { struct ds prereqs_s = DS_EMPTY_INITIALIZER; expr_format(prereqs, &prereqs_s); printf(" has prereqs %s\n", ds_cstr(&prereqs_s)); ds_destroy(&prereqs_s); } /* Now re-parse and re-format the string to verify that it's * round-trippable. */ struct ofpbuf ovnacts2; struct expr *prereqs2; ofpbuf_init(&ovnacts2, 0); error = ovnacts_parse_string(ds_cstr(&ovnacts_s), &pp, &ovnacts2, &prereqs2); if (!error) { struct ds ovnacts2_s = DS_EMPTY_INITIALIZER; ovnacts_format(ovnacts2.data, ovnacts2.size, &ovnacts2_s); if (strcmp(ds_cstr(&ovnacts_s), ds_cstr(&ovnacts2_s))) { printf(" bad reformat: %s\n", ds_cstr(&ovnacts2_s)); } ds_destroy(&ovnacts2_s); } else { printf(" reparse error: %s\n", error); free(error); } expr_destroy(prereqs2); ovnacts_free(ovnacts2.data, ovnacts2.size); ofpbuf_uninit(&ovnacts2); ds_destroy(&ovnacts_s); } else { printf(" %s\n", error); free(error); } expr_destroy(prereqs); ovnacts_free(ovnacts.data, ovnacts.size); ofpbuf_uninit(&ovnacts); simap_destroy(&ports); expr_symtab_destroy(&symtab); shash_destroy(&symtab); dhcp_opts_destroy(&dhcp_opts); dhcp_opts_destroy(&dhcpv6_opts); nd_ra_opts_destroy(&nd_ra_opts); ovn_extend_table_destroy(&group_table); ovn_extend_table_destroy(&meter_table); } static void test_parse_expr(const char *input) { struct shash symtab; struct shash addr_sets; struct shash port_groups; struct simap ports; struct expr *expr; char *error; create_symtab(&symtab); create_addr_sets(&addr_sets); create_port_groups(&port_groups); simap_init(&ports); simap_put(&ports, "eth0", 5); simap_put(&ports, "eth1", 6); simap_put(&ports, "LOCAL", ofp_to_u16(OFPP_LOCAL)); simap_put(&ports, "lsp1", 0x11); simap_put(&ports, "lsp2", 0x12); simap_put(&ports, "lsp3", 0x13); expr = expr_parse_string(input, &symtab, &addr_sets, &port_groups, &error); if (!error) { expr = expr_annotate(expr, &symtab, &error); } if (!error) { expr = expr_simplify(expr, is_chassis_resident_cb, &ports); expr = expr_normalize(expr); ovs_assert(expr_is_normalized(expr)); } if (!error) { struct hmap matches; expr_to_matches(expr, lookup_port_cb, &ports, &matches); expr_matches_print(&matches, stdout); expr_matches_destroy(&matches); } else { puts(error); free(error); } expr_destroy(expr); simap_destroy(&ports); expr_symtab_destroy(&symtab); shash_destroy(&symtab); expr_const_sets_destroy(&addr_sets); shash_destroy(&addr_sets); expr_const_sets_destroy(&port_groups); shash_destroy(&port_groups); } static bool lookup_atoi_cb(const void *aux OVS_UNUSED, const char *port_name, unsigned int *portp) { *portp = atoi(port_name); return true; } static void test_expr_to_packets(const char *input) { struct shash symtab; create_symtab(&symtab); struct flow uflow; char *error = expr_parse_microflow(input, &symtab, NULL, NULL, lookup_atoi_cb, NULL, &uflow); if (error) { puts(error); free(error); expr_symtab_destroy(&symtab); shash_destroy(&symtab); return; } uint64_t packet_stub[128 / 8]; struct dp_packet packet; dp_packet_use_stub(&packet, packet_stub, sizeof packet_stub); flow_compose(&packet, &uflow, NULL, 64); struct ds output = DS_EMPTY_INITIALIZER; const uint8_t *buf = dp_packet_data(&packet); for (int i = 0; i < dp_packet_size(&packet); i++) { uint8_t val = buf[i]; ds_put_format(&output, "%02"PRIx8, val); } puts(ds_cstr(&output)); ds_destroy(&output); dp_packet_uninit(&packet); expr_symtab_destroy(&symtab); shash_destroy(&symtab); } int LLVMFuzzerTestOneInput(const uint8_t *input_, size_t size) { /* Bail out if we cannot construct at least a 1 char string. */ const char *input = (const char *) input_; if (size < 2 || input[size - 1] != '\0' || strchr(input, '\n') || strlen(input) != size - 1) { return 0; } /* Disable logging to avoid write to disk. */ static bool isInit = false; if (!isInit) { vlog_set_verbosity("off"); isInit = true; } /* Parse, annotate, simplify, normalize expr and convert to flows. */ test_parse_expr(input); /* Parse actions. */ test_parse_actions(input); /* Test OVN lexer. */ test_lex(input); /* Expr to packets. */ test_expr_to_packets(input); return 0; }