12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- /* vim: set expandtab ts=4 sw=4: */
- /*
- * You may redistribute this program and/or modify it under the terms of
- * the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- #include "memory/Allocator.h"
- #include "net/SwitchAdapter.h"
- #include "util/Identity.h"
- #include "wire/SwitchHeader.h"
- #include "util/Linker.h"
- Linker_require("net/SwitchAdapter.c")
- struct SwitchAdapter_pvt
- {
- struct SwitchAdapter pub;
- struct Log* log;
- Identity
- };
- struct Header {
- struct SwitchHeader sh;
- uint32_t handle_be;
- };
- #define Header_SIZE 16
- Assert_compileTime(sizeof(struct Header) == Header_SIZE);
- static Iface_DEFUN incomingFromControlIf(struct Message* msg, struct Iface* controlIf)
- {
- struct SwitchAdapter_pvt* sa =
- Identity_containerOf(controlIf, struct SwitchAdapter_pvt, pub.controlIf);
- return Iface_next(&sa->pub.switchIf, msg);
- }
- static Iface_DEFUN incomingFromSessionManagerIf(struct Message* msg, struct Iface* sessionManagerIf)
- {
- struct SwitchAdapter_pvt* sa =
- Identity_containerOf(sessionManagerIf, struct SwitchAdapter_pvt, pub.sessionManagerIf);
- return Iface_next(&sa->pub.switchIf, msg);
- }
- static Iface_DEFUN incomingFromSwitchIf(struct Message* msg, struct Iface* switchIf)
- {
- struct SwitchAdapter_pvt* sa =
- Identity_containerOf(switchIf, struct SwitchAdapter_pvt, pub.switchIf);
- if (msg->length < Header_SIZE) {
- Log_debug(sa->log, "DROP runt");
- return 0;
- }
- Assert_true(!(((uintptr_t)msg->bytes) % 4) && "alignment");
- struct Header* hdr = (struct Header*) msg->bytes;
- // The label comes in reversed from the switch because the switch doesn't know that we aren't
- // another switch ready to parse more bits, bit reversing the label yields the source address.
- // (the field is still big endian!)
- hdr->sh.label_be = Bits_bitReverse64(hdr->sh.label_be);
- if (hdr->handle_be == 0xffffffff) {
- return Iface_next(&sa->pub.controlIf, msg);
- }
- return Iface_next(&sa->pub.sessionManagerIf, msg);
- }
- struct SwitchAdapter* SwitchAdapter_new(struct Allocator* allocator, struct Log* log)
- {
- struct Allocator* alloc = Allocator_child(allocator);
- struct SwitchAdapter_pvt* out = Allocator_calloc(alloc, sizeof(struct SwitchAdapter_pvt), 1);
- out->pub.controlIf.send = incomingFromControlIf;
- out->pub.sessionManagerIf.send = incomingFromSessionManagerIf;
- out->pub.switchIf.send = incomingFromSwitchIf;
- out->log = log;
- Identity_set(out);
- return &out->pub;
- }
|